别在说饿汉式单例是项目启动加载了,除非面试官也是菜鸡

常见的说法都是说饿汉式单例模式是项目启动的时候加载,会占用项目资源?但是你有没有认识到,这个说法合理吗?

1.准备知识

1.1 JVM类加载机制

JVM那点事-虚拟机类加载机制

一般场景下,new关键字、调用static常量或者方法、反射均会将类初始化。

image.png

初始化的过程中,完成静态属性、常量属性的赋值。

image.png

1.2 饿汉式单例代码

@Slf4j
public class Singletoneh {
    private final static Singletoneh instance = new Singletoneh();

    private Singletoneh() {
        log.info("==============>我");
    }

    public static Singletoneh getInstance() {
        return instance;
    }



    public void say() {
        System.out.println("【饿汉模式】—实现单例!");
    }

}

2. 饿汉式单例真的是项目启动的时候加载的JVM中吗?

不是!正确的说法:饿汉式单例是在类初始化的时候加载到JVM中。

而类初始化的时机:

  1. new关键字:单例模式构造方法私有化,无法进行调用;
  2. 静态属性/方法:一般是获取单例instance时调用。即:饿汉式单例模式也是在获取单例的时候才会创建单例对象,且放在JVM中。

所以:饿汉式单例模式和懒汉式单例模式初始化时机大部分相同。

但是饿汉式单例本质上是类初始化单例才加载到JVM中,懒汉式单例是真正调用getInstance方法时单例才加载到JVM中。

饿汉式单例可以在如下场景下,不调用getInstance方法,单例对象加载到JVM虚拟机。

  • 饿汉式单例中存在其他静态方法,在调用static getInstance()前调用其他静态方法可以完成单例初始化;
  • 反射调用饿汉式单例的私有构造方法,即可完成初始化;

3. 饿汉式使用final能提前加载吗?

不能!final修饰的常量不会触发类的初始化。

image.png

推荐阅读

关于单例模式饿汉模式的思考

单例模式实现的几种方案

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容