Java初始化块和单例类

Java初始化块和单例类

开发工具与关键技术:工具:myeclipse  技术: static,synchronized 
作者:吴东梅
撰写时间:2019-05-02

Java初始化块
初始化块根据是否使用static修饰分为两类:

  1. 不使用static修饰的是普通初始化块。
  2. 使用static修饰的是静态初始化块。
    普通初始化块
    (1) 初始化块相当于是对构造器的补充,用于创建对象时给对象的初始化,在构造器之前执行。
    (2) 如果一段初始化代码对所有构造器完全相同,且无需接收参数,那就可以将其提取到非静态初始化代码块中。
    (3) 实际上,经过编译后,非静态块已经添加到构造器中,且位于所有构造器代码的前面。
    静态初始化块
    (1) 静态初始化块用static修饰,又叫类初始化块。
    (2) 静态初始化块负责对类进行初始化,因此类初始化块是在类初始化阶段就执行。
    (3) 静态块跟静态方法一样,不能访问非静态成员。
    (4) 因为静态块是在类的初始化阶段完成的,因此在创建某个类的第二个对象时,该类的静态块就不会执行了。

一、 首先我们先来了解一下在单个类中普通初始化块、静态初始化块、构造器的执行顺序。
在单个类中,静态初始化块(多个时从上往下执行),初始化块(多个时从上往下执行),构造器。如下图所示:
Java初始化块和单例类_第1张图片
从上图中,我们可以看出,在类中有静态初始化块,有几个普通初始化块,有构造器,它们的顺序并没有按照上面我们说的顺序去写,那么下面我们来验证一下它们的执行顺序是否就如我们上面所说的那样的,如图所示:
Java初始化块和单例类_第2张图片

二、 接下来我们了解在多个类的继承中,普通初始化块、静态初始化块、构造器的执行顺序。
在继承中,先后执行父类A的静态块,父类B的静态块,最后子类的静态块,然后再执行父类A的非静态块和构造器,然后是B类的非静态块和构造器,最后执行子类的非静态块和构造器。
先定义好父类和子类,实现好他们之间的继承关系,如下图所示:有两个父类一个子类,父类和子类里面都定义了普通初始化块和静态初始化块和构造器。
Java初始化块和单例类_第3张图片
现在我们来写main方法,执行一下上面写的类,来验证一下效果,如下图所示:
Java初始化块和单例类_第4张图片
事实证明上面我们了解到的都是对的,但是如果我们再在main方法下面第二次执行上面的类的方法,效果会怎么样呢?如下图所示:
Java初始化块和单例类_第5张图片
如上图所示,静态初始化块在第一次执行完之后第二次便不会再执行了,因为静态块是在类的初始化阶段完成的,因此在创建某个类的第二个对象时,该类的静态块就不会执行了。

Java 单例模式
所谓单例,就是让整个项目在运行过程当中只会new出一个实例出来。
适用场景: 1. 需要生成唯一序列的环境。
2. 需要频繁实例化然后销毁的对象。 3. 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。 4. 方便资源相互通信的环境。
Java 单例模式有五种实现方式: 一、饿汉式: 特点:线程安全,调用效率高,但是不能延时加载。
如下图所示:先写好一个饿汉式的的方法
Java初始化块和单例类_第6张图片
然后写一个Demo的类的方法来调用上面写好的饿汉式单例,如下图所示,无论你定义多少个变量,它们最后的值都是相等的,如下图所示:
Java初始化块和单例类_第7张图片
二、懒汉式: 特点:线程安全,调用效率不高,但是能延时加载 如下图所示,先写好一个懒汉式的类的方法
Java初始化块和单例类_第8张图片
写好之后,在main方法里面调用这个方法的结果如下图所示:
Java初始化块和单例类_第9张图片
三、 Double CheckLock实现单例:
特点:Double CheckLock也就是双重锁判断机制(由于JVM底层模型原因,偶尔会出问题,不建议使用),是在懒汉式单例上发展而来。偶尔的几率很小很小,但是一但出现便很难挽回。
声明类的方法跟懒汉式差不多,如下图所示:
Java初始化块和单例类_第10张图片
在main方法调用后,效果图所下:
Java初始化块和单例类_第11张图片
四、 静态内部类模式:
特点:线程安全,调用效率高,可以延时加载 声明一个静态内部类,写法如下图所示:
Java初始化块和单例类_第12张图片
在main方法里面调用之后,运行结果如下图所示:
Java初始化块和单例类_第13张图片
五、 枚举类:
特点:线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用
声明一个枚举类,如下图所示:
Java初始化块和单例类_第14张图片
在main方法调用之后,效果图如下:无论循环多少次,最后它们的值都是相等的。
Java初始化块和单例类_第15张图片
六、如何选择 1、单例对象占用资源少,不需要延时加载时:枚举 好于 饿汉。
2、单例对象占用资源多,需要延时加载时:静态内部类 好于 懒汉式。

你可能感兴趣的:(Java)