饿汉式单例模式测试
public class Singleton { private Singleton() {} private static final Singleton single = new Singleton(); //静态工厂方法 public static Singleton getInstance() { return single; } }
静态内部类实现的懒汉式单例模式spa
public class Singleton { private static class LazyHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return LazyHolder.INSTANCE; } }
第一种方式是饿汉式单例模式,比较容易理解的,即类在加载后就实例化了。debug
第二种方式是懒汉式单例模式,且使用了静态内部类实现。可能不少人一开始看到的时候会以为,使用这种方式的单例模式也是在类加载后就实例化了,其实否则,若是咱们在以上两种单例模式的构造器中随意加入一行打印字符串的代码,而后加载一下以上两个类就会发现区别。code
例如:都将构造器改成对象
private Singleton(){ System.out.println("init"); }
添加测试使用的main方法blog
public static void main(String[] args) { Singleton s = getInstance(); }
使用debug模式,在Singleton s = getInstance();一行处打上断点,并执行main方法。因为打了断点,因此执行main方法后会在执行Singleton s = getInstance();前中止,但此时第一种方式的单例模式打印出了“init”字样,而第二种方式单例模式并未打印,直到执行Singleton s = getInstance();一行代码后才打印“init”字样。也就说明了第一种是饿汉式,第二种是懒汉式。字符串
关于使用静态内部类实现的单例模式为何是懒汉式的,其实和静态内部类有关。get
内部类分为对象级别(非静态内部类)和类级别(静态内部类),类级内部类指的是,有static修饰的成员变量的内部类。若是没有static修饰的成员变量的内部类被称为对象级内部类。
it
类级内部类至关于其外部类的static成员,它的对象与外部类对象间不存在依赖关系,相互独立,所以可直接建立。而对象级内部类的实例,是必须绑定在外部对象实例上的。class
类级内部类只有在第一次被使用的时候才被会装载。