知识
1, 面向对象基础知识点:面向过程强调的是功能行为,面向对象强调具备功能的对象;三大特征:封装,继承,多态
2, 匿名对象:创建对象后直接使用,而不需要给对象命名。
当对对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简化。如果对一个对象进行多个成员调用,必须给这个对象起个名字。另一种使用:作为参数传递给方法,节省内存开销。
3, 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式。原则:将不需要对外提供的内容都隐藏起来。 把属性隐藏,提供公共方法对其访问(set和get方法)。
4, 构造函数:给对象初始化,对象一创建即调用
5, 构造代码块:给对象初始化,对象创建就调用,而且优先于构造函数执行,是给所有的对象初始化
6, This关键字:1)代表的是本类的对象;2)多个构造函数之间后者调用前者this(前者参数),而且要放在第一句
7, Static静态:修饰符;
特点:1.随着类的加载而加载,随着类的消失而消失 2.优先类的对象存在: 静态对象是先存在,对象是后存在的3.被所有对象所共享 4.可以直接被类名直接调用
注:1.静态方法只能访问静态成员(用一个类中,静态方法访问不到其中的非静态变量)非静态方法既可以访问静态也可以访问非静态
2.静态方法中不可以定义this,super关键字;因为静态方法优先于对象存在,所以静态方法中不可以出现this
3.主函数是静态的
静态好处:对对象的共享数据进行单独空间的存储,节省内存,没有必要每一个对象中都存储一份;弊:生命周期过长,访问出现局限性(静态虽好,只能访问静态)
8, Static重要应用-工具类:
将常用的方法代理封装到一个类中,类中的那些常用方法用static修饰,这样调用的时候可以直接类名.方法;为了避免被实例化,把构造方法私有化;好处:不需要实例化,节省了空间
9, 静态代码块:给类进行初始化:随着类的加载而执行,用到类就会加载;Demo d=null;这不会加载; 初始化执行顺序:静态代码块—构造代码块—构造函数
10, 单例设计模式:
思路:单例设计模式:解决一个类在内存只存在一个对象
想要保证对象唯一:1,为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象2,还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象3,了方便其他程序对自定义对象的访问,可以对外提供一些访问方式
这三部怎么用代码体现?
1, 将构造函数私有化 ------private Single() { }
2, 在类中创建一个本类对象 Single s=new Single();
3, 提供一个方法可以获取该对象 public Single getInstance(){ return s;}
能用类名调用 方法要 静态 静态方法只能调用静态对象 s 用static修饰 成员变量一般私有化 然后 s 用private修饰下
即private Single() { } private static Single s=new Single();
public static Single getInstance(){ return s;}
使用 Single s=Single.getInstance();
两种形式:饿汉式:当类加载,就自己创建好一个实例,保证绝对唯一
Class Single{
private Single() { }
private static Single s=new Single();
public static Single getInstance(){
return s;
}
}
先初始化对象,成为饿汉式S
懒汉式:只有调用了getInstance方法时,才建立对象(延迟加载)
Class Single{
private Single() { }
private static Single s=null;
public static Single getInstance(){
if(s==null) s=new Single();
return s;
}
}
懒汉式出现线程问题:解决方法:同步加锁
11, 继承:类与类之间的所属关系is a(继承原则),java不支持多继承,支持多实现
12, 其他关系:聚集:has a 组合:里面的一部分;聚合:并不是其中的一部分
13, Super和this的区别:this指本类对象(也就包含了父类的使用),super只代表的是父类;两者都类似于指针:父类中有this指针,子类中有this和super指针
14, 重写(覆盖):子类中的方法跟父类一样;注意:1)子类覆盖父类,必须保证子类权限大于父类权限才可以覆盖,否则编译失败;2)静态只能覆盖静态
15, 构造函数的使用:先运行父类的构造函数,再使用子类的构造函数
16, Final最终,修饰符,可修饰类,函数,变量;final修饰的是引用的时候,不能修改的是引用而不是指向的内容;
17, 抽象类:类之间有相同的功能,但是功能的主体不一样,这时向上抽取出功能定义--抽象类;特点:1, 抽象方法一定在抽象类中;2, 抽象方法和抽象类都必须被abstract关键字修饰;3, 抽象类不可以用new创建对象,因为创建对象没意义;4, 抽象类中的方法要被使用,必须由于类复写起所有的抽象方法后,建立子类对象调用,如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类
18, 模板方法模式:final 修饰里面的方法,写进一个类中,子类继承时,只需要添加自己需要的代码即可;使用:计算程序运行时间
19, 接口:特殊的抽象类 interface定义接口
特点:1,接口中常见定义:常量,抽象方法2,接口中成员都有固定修饰符; 常量:public static final 方法:public abstract 记住:接口中的成员都是public的;3,接口可以被类多实现,一个类可以使用多个接口,类与类之间继承关系(单继承),类与接口之间是实现关系,接口与接口之间是继承关系(接口与接口之间可以实现多继承)
20, 多态:某一种事物的多种存在形态;
理解:子类A和B继承父类P,当用父类P创建对象的时候,可以实例化为A类实例,也可以实例化成B类实例,也就相当于P创建的实例可以在不同的情况下具有不同的属性和方法
1, 多态的体现,
父类的引用指向了自己的子类对象
父类的引用也可以接受自己的子对象
2, 多态的前提
必须是类与类之间有关系,要么继承,要么实现
通常还有一个前提,存在覆盖
3, 多态的好处
多态的出现大大提高了代码的扩展性
4, 多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类的成员
21, 多态的体现:向上转型(类型提升);注意:多态自始至终都是子类对象在做变化;多态函数的使用看左边,运行看右边,成员变量无论编译和运行,都参考左边。
22, 内部类:将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类);访问特点:内部类可以直接访问外部类中的成员,包括私有成员;而外部类要访问内部类中的成员必须要建立内部类的对象。
23, Object类的equals方法和toString方法:equals是对对象的比较方法,因为其直接值为地址空间,值的比较要自己定义;toString默认输出:所属类名@对象的hash值:getClass.getName()+”@”+Integer.toHexString(hashCode())
24, 内部类的定义:当描述事物时,事物的内部还有事物,该事物用内部类来描述,因为内部事务在使用外部事物的内容。当内部类不需要对外开放时用private修饰。
25, 内部类:百度了解:http://baike.baidu.com/view/884886.htm
内部类分为三种:1)在一个类(外部类)中直接定义的内部类;2)在一个方法(外部类的方法)中定义的内部类;3)匿名内部类;
表现形式:静态内部类;成员内部类;局部内部类;匿名内部类;
内部类的理解参考:http://zhidao.baidu.com/question/413215044.html 下面的解答
26, 异常机制:程序中出现的不正常情况就是异常;java对出现的问题中不严重的部分通过exception类进行描述,exception可以使用针对的处理方式进行处理。
27, 处理方式:throws Exception;try{。。。}catch(..){..} 两种
JVM默认的异常处理机制就是在调用printStackTrace方法打印异常的堆栈跟踪信息。
28, 异常声明-throws(声明该方法有可能出现的问题)
29, 多异常处理:在函数上声明异常,便于提高安全性,让调用出进行处理,不处理编译失败
多种异常时:声明更具体,处理的更具体1, 声明异常时,建议声明更为具体的异常,这样处理的可以更具体2, 对方声明几个异常,就对应有几个catch块,不要定义多余的catch块;如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面;建议在进行catch处理时,catch中一定要定义具体处理方式,不要简单定义一句e.printStackTrace();也不要简单的就书写一条输出语句
30, 自定义异常:将特有的问题,进行自定义的异常封装;
方法:继承Exception类;构造方法中通过super语句将异常信息传递给父类;就可以直接通过getmessage方法获取自定义的异常信息
自定义异常:定义类继承Exception或者Runtimeexception
1, 为了让该自定义类具备可抛性,
2, 让该类具备操作异常的共性方法
当要定义自定义异常的信息时,可以使用父类已经定义好的功能。
异常异常信息传递给父类的构造函数
Class MyException extends Exception{
MyException (String message){
Super(message);
}
}
自定义异常是按照java的面向对象思想,将程序中出现的特有问题进行封装
31, throws和throw的区别:Throws使用在函数上,throw使用在函数内;Throws后面跟的是异常类,可以跟多个,用逗号隔开;Throw后跟的是异常对象;
32, RuntimeException:Exception中特殊的子类异常RuntimeException运行时异常;如果在函数内部抛出该异常,函数上可以不用声明,编译一样通过;如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过;RuntimeException的异常不需要声明,当发生时,自动停止(包含其子类),让用户处理;RuntimeException是编译时不被检测的异常。
33, Finally是一定会执行的代码,很多程序中有跟资源有关的操作,操作完必须进行关闭,这就是finally存在的意义;当程序中有return时,finally一定在return之前执行。Finally只有一种情况不会执行,当执行到system.exit(0);finally不会执行;
34, 异常注意的几点:当函数内容有throw抛出异常对象,并未进行try处理,必须要在函数上声明,否则编译失败,注意,runtimeException除外,也就是,函数内如果抛出的runtimeexception异常,函数上可以不用声明;如果函数声明了异常,调用者需要进行处理,处理方式可throws可以try;异常有两种:编译时被检测异常(必须处理);运行时异常(在编译时,编译器不检查;该异常的发生,建议不处理,让程序停止,对代码修正)
35, 异常的好处:1,将问题进行封装;2,将正常流程代码和问题处理代码相分离,方便于阅读。异常的处理原则:1,处理方式有两种,try和throws;2,调用到抛出异常的功能时,抛出几个,就处理几个,一个try对应多个catch;3,多个catch,父类的catch放到最下面;4,Catch内,需要定义针对性的处理方式,不要简单的定义printstacktrace,输出语句。也不要不写。
当捕捉到的异常,本功能处理不了时,可以继续在catch中抛出
Try{throw new AException();}
Catch(AException e){throw e;}
如果该异常处理不了,但并不属于该功能出现的异常,可以将异常转换后,再抛出和该功能相关的异常
或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,当调用者知道,并处理,也可以将捕获异常处理后转换新的异常
Try{throw new AException();}
Catch(AException e){throw new AException();}
比如,汇款的例子
异常的注意事项:在子父类覆盖时,1,子类抛出的异常是父类异常的子类或者子集;2,如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛
36, 包-Package:对类文件进行分类,给类提供多层命名空间,写在程序文件的第一行,类名全称为:包名.类名;
编译带包的文件:javac –d . mingzi.java 运行文件: java baoming.mingzi
37, 包与包之间的访问:包与包之间可以使用的权限只有两种:public protected
具体的访问规则:
Public protected default private
同一个类中 ok ok ok ok
同一个包中 ok ok ok
子类 ok ok
不同包中 ok
38, 导入import:实际开发中,导入包是使用哪个类就导入哪个class文件
39, jar包:java的压缩包,class文件集合
40, 异常覆盖中的细节:
1,子类在覆盖父类时,如果父类中被覆盖的方法抛出了异常,那么子类覆盖的方法,只能抛出相同的异常,或者该异常的子类。2,如果父类的被覆盖方法抛出了多个异常,子类在覆盖时,只能抛出这些异常的子集。3,如果被覆盖的方法没有抛出异常,子类也不允许抛出异常。如果子类中真的出现异常,只能在子类方法内进行try处理,绝对不允许throws声明。万一处理不了呢?你可以选择抛出运行时异常。
问题:
- 多态的理解:多态,是面向对象的程序设计语言最核心的特征。多态,意味着一个对象有着多重特征,可以在特定的情况下,表现不同的状态,从而对应着不同的属性和方法。子类A和B继承父类P,当用父类P创建对象的时候,可以实例化为A类实例,也可以实例化成B类实例,也就相当于P创建的实例可以在不同的情况下具有不同的属性和方法
- 构造函数和构造代码块区别:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。
- 什么时候使用静态?当对象中出现共享数据时,该数据被静态修饰
- 面向对象的理解:三个特点,举个例子
- 面向对象在程序中的基本思想:万物接对象
- 类与对象的关系:类是一系列对象属性的抽取,对象是符合该类的具体实例
- 成员变量和局部变量的区别?成员变量(面向对象的概念):在类主体的变量部分中定义的变量,也称为属性。局部变量指在程序中,只在特定过程或函数中可以访问的变量,是相对与全局变量而言的。(面向过程和面向对象中均有的)
- 对象创建的内存?在堆中开辟空间,把对其引用的地址赋给栈内存中的变量
- 构造函数和一般函数的区别:1) 构造函数是在对象一建立就运行,给对象初始化,而一般方法是对象调用才执行,给对象添加的功能;2) 一个对象建立,构造函数只运行一次,而一般方法可以被该对象调用多次
- 构造函数什么时候用?当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中
- 构造代码块的作用?给对象初始化,对象创建就调用,而且优先于构造函数执行,是给所有的对象初始化;与构造函数的区别是:构造函数只是初始化部分对象(参数限定的部分),构造代码块是对所有的对象初始化
- this关键字的特点和使用以及应用场景?this代表的是本类的对象,代表他所在函数所属对象的应用;应用:当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。但凡本类功能内部使用了本类对象,都用this表示;多个构造函数之间后者调用前者,对this的调用必须是构造函数中的第一个语句,因为初始化要先执行。
- 静态和非静态的区别。说一下内存。1.静态方法只能访问静态成员,非静态方法既可以访问静态也可以访问非静态;2.静态方法中不可以定义this,super关键字(因为静态方法优先于对象存在,所以静态方法中不可以出现this);3,静态代码是放在静态代码区,随着类的加载而进入内存,随着类的消失而消失;4,优先类的对象存在,被所有对象共享;可以直接被类名调用
- 成员变量和静态变量的区别?存放位置不同:(成员变量:栈内存;静态变量:静态代码块)加载的时间不一样(静态代码在对象之前加载进内存)
- 静态的特点以及注意事项?Static特点:1.随着类的加载而加载,随着类的消失而消失2.优先类的对象存在: 静态对象是先存在,对象是后存在的3.被所有对象所共享 4.可以直接被类名所调用;注意事项:1.静态方法只能访问静态成员(用一个类中,静态方法访问不到其中的非静态变量),非静态方法既可以访问静态也可以访问非静态;2.静态方法中不可以定义this,super关键字 因为静态方法优先于对象存在,所以静态方法中不可以出现this 3.主函数是静态的
- 什么时候使用静态?当对象中出现共享数据时,该数据被静态修饰
- 静态代码块的特点和作用?用于给类进行初始化;特点:随着类的加载而执行,只执行一次(类的加载是要用到类的内容,Demo d=null;这不表示被加载,没有指向)
- 单例设计模式解决的问题,以及设计思想。代码体现,全部都要会!
单例设计模式:保证了一个类在内存中只能有一个对象。比如多程序访问同一个配置文件。希望多程序操作的都是同一个配置文件中的数据。那么就需要保证该配置文件对象的唯一性。
思路:怎么做才能保证这个对象是唯一的呢?
1,其他程序随时用new创建该类对象,无法控制个数。 结论:不让其他程序创建该类的对象。因为不可以控制。
2,不让其他程序创建,该类在本类中自己创建一个对象。
3,该类将创建的对象对外提供,让其他程序获取并使用。
步骤:
1,怎么实现不让其他程序该类对象呢? 将该类中的构造函数私有化。
2,在本类中创建一个本类对象。
3,定义一个方法,返回值类型是本类类型。让其他程序通过该方法就可以获取到该类对象。
- 懒汉式和饿汉式的区别?
饿汉式:
public class Singleton{
private static Singleton singleton = new Singleton ();
private Singleton (){}
public Singleton getInstance(){return singletion;}
}
懒汉式:
public class Singleton{
private static Singleton singleton = null;
public static synchronized synchronized getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
比较:
饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变;懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的;推荐使用第一种-饿汉式
- 继承的好处?1, 提高了代码的复用性2,让类与类之间产生了关系,有了这个关系,才有了多态的特征
- java改良多继承的原因?会产生调用的不确定性。一个类如果有多个父类的话,有相同方法的时候,会产生调用的不确定
- 当使用一个已存在的继承体系时,该如何更快应用 ?1,查阅该体系中的顶层类的内容。因为通过该类可以了解该体系的基本功能。2,创建最子类的对象,即可以调用共性的基本功能,也可以使用子类的特有功能。简单说:看父类内容,建子类对象使用。
- 什么时候用继承?必须是事物之间存在着所属关系时,才定义继承。所属关系:xxx是zzz中的一种。 用英文表示: is a关系。
- super和this的特点?super:代表的是父类。用法和this相似。this代表本类对象的引用。super代表父类所属的空间。
- 覆盖的特点,何时应用,注意事项?子类跟父类具有相似的功能,但又有所不同,可以对父类中的该方法进行复写;覆盖注意事项:1,子类覆盖父类时,必须要保证覆盖方法的权限大于等于被覆盖的方法的权限.2,覆盖方法有静态修饰时,静态只能覆盖静态,或者被静态覆盖。
- final特点和应用。常量什么时候定义?final关键字的特点:1,final是一个修饰符,既可以修饰类,又可以修饰方法,还可以修饰变量。2,final修饰的类不可以被继承。3,final修饰的方法不可以被覆盖。4,final修饰的变量是一个常量,只能赋值一次。 为了将固定的一些数据方便使用,会给这些起一个容易阅读的名称, 为了防止名称存储的数据改变。用final修饰。一般为final修饰的变量名称都是大写字母组成,如果有多个单词, 每个单词之间用下划线分隔。在开发时,一旦程序中有出现固定的数据,一定要将其用一个容易阅读的名称存储,并用final修饰。
- 抽象类的特点,以及细节?抽象类的特点:1,没有方法体的方法是抽象方法,一定定义在抽象类中。2,抽象类和抽象方法必须用abstract关键字所修饰。3,抽象类不可以被实例化。为啥?因为调用抽象方法没有意义。4,抽象类必须由其子类覆盖掉所有的抽象方法后,其子类才可以进行实例化。 否则,该子类还是一个抽象类。细节问题:1,抽象类一定是个父类?是,2,抽象类是否有构造函数?有,因为是给子类对象提供初始化动作的。3,抽象类中是否可以不定义抽象方法?可以的。为了不让其创建对象。这种情况在java的体系中就有存在,windowAdapter;4,抽象关键字不能和哪些关键字共存。 final : private: static :
- 接口的表现形式的特点:接口是对外暴露的规则。接口是程序的功能的扩展。接口可以用来多实现
- 多实现和多继承的区别?多实现是接口中没有具体的实现部分,而且需要在实现的类中具体实现,多继承则是在每个类中都有自己的实现方式,这个是java不支持的
- 抽象类和接口的区别?接口中的方法都是抽象的,抽象类则不一定;抽象类可以继承不可以实现,接口既可以继承,又可以实现;
- 多态的体现,前提,好处,弊端。1,多态的体现,父类的引用指向了自己的子类对象,父类的引用也可以接受自己的子对象2,多态的前提:必须是类与类之间有关系,要么继承,要么实现;通常还有一个前提,存在覆盖3,多态的好处:多态的出现大大提高了代码的扩展性;4,多态的弊端:提高了扩展性,但是只能使用父类的引用访问父类的成员
- 多态的转型什么时候使用?将子类实例转成父类实例,向上转型
- Object类的常见方法。equals,toString,getClass,hashCode.
- 为什么要将一个类定义成内部类?类是用于描述事物的,而事物中如果还有具体的事物,而且这个内部的事物在访问着所属事物中的内容。这时这个内部的事物,也需要用到类来描述。这个类就是内部类。
- 匿名内部类的使用和细节(面试题)。 格式:new 父类名或接口名().成员。匿名内部类使用细节:当接口类型参数,该接口中方法不超过3个,可以使用匿名内部类作为函数的参数进行传递,这样简化了书写。但是接口方法较多时,不要使用匿名内部类。影响阅读性。
- 异常的思想和体系特点?捕获程序中出现的不正常情况,使其不影响程序的正常运行;异常体系最大的特点是该体系中的类和对象都具备可抛性。
- throws和throw的如何使用?throws使用在函数上,throw使用在函数内;throws后面跟的是异常类,可以跟多个,用逗号隔开;throw后跟的是异常对象
- 什么时候try 什么时候throws?异常最终要被处理的,一般是向上抛(throws);try是捕获抛出的异常;就是即使是throws只是抛给了上一层,最终还是需要处理的;
- 编译时被检测异常和运行时异常的区别?编译时的异常可以经简单处理解决,运行期的异常一般是要进行修改代码
程序:1,自定义异常类:
1 class FuShuException extends Exception // getMessage(); 2 { 3 private int value; 4 FuShuException() { 5 super(); 6 } 7 FuShuException(String msg, int value) { 8 super(msg); 9 this.value = value; 10 } 11 public int getValue() { 12 return value; 13 } 14 } 15 16 class Demo { 17 int div(int a, int b) throws FuShuException { 18 if (b < 0) 19 throw new FuShuException("出现了除数是负数的情况------ / by fushu", b);// 手动通过throw关键字抛出一个自定义异常对象。 20 return a / b; 21 } 22 } 23 24 public class myExcept { 25 public static void main(String[] args) { 26 Demo d = new Demo(); 27 try { 28 System.out.println("x=" + d.div(4, -9)); 29 } catch (FuShuException e) { 30 // TODO Auto-generated catch block 31 // System.out.println(e.toString()); 32 e.printStackTrace(); 33 } 34 } 35 }
2,模板模式:
1 /* 2 需求:获取一段程序运行的时间。 3 原理:获取程序开始和结束的时间并相减即可。 4 5 获取时间:System.currentTimeMillis(); 6 7 当代码完成优化后,就可以解决这类问题。 8 9 这种方式,模版方法设计模式。 10 11 什么是模版方法呢? 12 在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分, 13 那么这时就将不确定的部分暴露出去。由该类的子类去完成。 14 15 16 */ 17 18 abstract class GetTime { 19 public final void getTime() { 20 long start = System.currentTimeMillis(); 21 22 runcode(); 23 24 long end = System.currentTimeMillis(); 25 26 System.out.println("毫秒:" + (end - start)); 27 } 28 29 public abstract void runcode(); 30 31 } 32 33 class SubTime extends GetTime { 34 public void runcode() { 35 for (int x = 0; x < 4000; x++) { 36 System.out.print(x); 37 } 38 } 39 } 40 41 class TemplateDemo { 42 public static void main(String[] args) { 43 // GetTime gt = new GetTime(); 44 SubTime gt = new SubTime(); 45 gt.getTime(); 46 } 47 }
3,单例设计模式
1 /* 2 单例设计模式:保证了一个类在内存中只能有一个对象。比如多程序访问同一个配置文件。希望多程序操作的都是同一个配置文件中的数据。那么就需要保证该配置文件对象的唯一性。 3 思路:怎么做才能保证这个对象是唯一的呢? 4 1,其他程序随时用new创建该类对象,无法控制个数。 结论:不让其他程序创建该类的对象。因为不可以控制。 5 2,不让其他程序创建,该类在本类中自己创建一个对象。 6 3,该类将创建的对象对外提供,让其他程序获取并使用。 7 步骤: 8 1,怎么实现不让其他程序该类对象呢? 将该类中的构造函数私有化。 9 2,在本类中创建一个本类对象。 10 3,定义一个方法,返回值类型是本类类型。让其他程序通过该方法就可以获取到该类对象。 11 12 */ 13 14 饿汉式: 15 public class Singleton{ 16 private static Singleton singleton = new Singleton (); 17 private Singleton (){} 18 public Singleton getInstance(){return singletion;} 19 } 20 21 懒汉式: 22 public class Singleton{ 23 private static Singleton singleton = null; 24 public static synchronized synchronized getInstance(){ 25 if(singleton==null){ 26 singleton = new Singleton(); 27 } 28 return singleton; 29 } 30 } 31 比较: 32 饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变;懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的;推荐使用第一种-饿汉式