自学内容网 自学内容网

代码块和单例模式

代码块

        在 Java 中使用一对花括号 { } 包裹的代码称之为代码块。

        根据代码块在类中定义的位置不同,可以分为: 构造代码块、静态代码块、局部代码块。

构造代码块

        定义在类中的成员位置,跟构造器是同级关系,即定义在类中的方法之外,并且不使用关键字 static 修饰的的代码块。

特点:

(1)构造代码块在创建实例对象的时候优先于构造器执行,因此可以使用构造代码块对新创建出来的实例进行初始化的操作。

(2)每一次使用构造器创建一个实例对象的时候,构造代码块均会执行一次。

(3)如果一个类中存在多个构造代码块,那么在使用构造器创建该类类型的实例对象的时候,这多个代码块均会执行,并且是按照它们在类中定义的先后顺序执行,但是不管有多少个构造代码块,都是在构造器执行之前执行的。

(4)对于构造代码块而言,它可以定义在类中的任意成员位置,和成员变量、成员方法以及构造器之间是不分先后顺序的,但是对于多个构造代码块而言是分先后顺序的。

静态代码块

        定义在类中的成员位置,即定义在类中的方法之外,并使用关键字 static 修饰的的代码块,使用关键字 static 修饰的静态代码块是属于类的。

特点:

(1)静态代码块是优先于构造代码块执行的,并在类第一次被使用的时候执行。

(2)静态代码块是属于类的,只在类第一次被使用的时候执行,因此静态代码块执行过程一次之后,以后以任何形式去使用该类的时候,静态代码块都不会再执行,即静态代码块最多执行一次。

(3)静态代码块是属于类的,在类第一次被使用的时候执行,因此可以我们使用静态代码块对类进行初始化的操作,例如给类中的静态成员变量赋值,不能给非静态成员变量赋值,因为静态成员只能够调用静态成员。

局部代码块

        定义在方法或者语句中(if、while、for、switch 等语句)的代码块。

        它是以一对花括号来划分代码的边界,对于局部代码块我们主要需要关注的是在不同的局部代码块中定义的变量的作用域即可。

        定义在代码块中的变量只适用于改代码块的内部,出了该代码块的花括号边界 { },变量就不起作用了。

单例模式

        在声明定义出一个类之后,要求这个类永远只能够创建出一个实例对象。

分析:

(1)要求永远只能够创建出一个实例对象,即类的构造器不能够随意使用,可以把构造器使用关键字 private 进行修饰。

(2)构造器一旦私有化之间就不能够随意调用,也就无法创建实例对象,此时可以在类中提供一个获得该类类型实例对象的方法,该方法必须使用关键字 static 修饰,因为无法创建对象,也就无法直接调用非 static 方法,同时必须要求无论调用多少次该方法返回的永远是同一个该类类型的实例对象。

构造方法私有化

        我们以后可能碰到很多 Java API 中提供的类并且类中的构造器都使用了关键字 private 修饰,这么 做的目的就是为了防止随意的创建实例对象,保证实例对象的唯一性或者直接不让创建实例对象。

         通过构造器的私有化,达到了控制是否可以任意创建实例对象的目的,但是如果想要得到该类型的实例对象,就必须提供可以不通过实例对象访问的使用关键字 static 修饰的静态方法,在静态方法内部返回一个实例对象,是否实现单例就可以通过控制静态方法内部是否永远返回同一个实例对象来实现。

示例:

public class Person {

    static Person instance = new Person();
    /**
     * 构造器私有化
     */
    private Person() {
    }
    /**
     * 提供一个可以直接通过类名方法的静态方法 getInstance(),并让该静态方法的返回值类型
     * 为 Person,即使用类名调用该静态方法可以获得一个 Person 类型的实例对象,
     * 是否是单例,就通过控制返回的 Person 类型的实例对象是否永远是同一个 
     * Person 类型的实例对象
     * @return 
     */
    public static Person getInstance() {
        return new Person();
        //return instance;
    }
}

这就需要用到单例模式。

单例模式分类

        懒汉模式、饿汉模式;

懒汉模式

        我们不需要使用这个类的唯一实例对象时就不创建,只有在第一次需要使用这个唯一实例对象的时候创建,并且以后每次需要使用该类类型的实例对象的时候,都使用这个唯一 实例对象。

        当类第一次使用被加载到内存中的时候并不是立马创建这个类的唯一实例对象,因此加载效率较高,但是在第一次获取该类的唯一实例对象时需要新建,因此在第一次获取这个唯一实例对象的效率较慢。

代码实现:

/**
 * 懒汉模式
 */
public class LazySingleton {
    //声明一个成员变量,表示该类类型的唯一实例对象,在没有需要使用该唯一实例对象之前创建
    //instance 变量的值默认为 null
    private static LazySingleton instance;

    /**
     * 私有化的构造器
     */
    private LazySingleton() {
    }

    /**
     * 获取该类唯一实例对象的静态方法
     * @return
     */
    public static LazySingleton getInstance() {
        if (instance == null) {
        //第一次需要使用该唯一实例对象时创建
            instance = new LazySingleton();
        }
        return instance;
    }
}

饿汉模式

        不管我们需要使用这个类的唯一实例对象,在类第一次使用被加载到内存 中的时候就立马创建这个类的唯一实例对象,因此加载效率较低,以后每一次需要使用这个类的唯一实 例对象时,把类第一次被使用加载到内存中时创建出来的唯一实例对象直接拿来使用,因此第一次获取 这个唯一实例对象的效率较高。

代码实现:

/**
 * 饿汉模式
 */
public class HungrySingleton {
    //不管需不需要使用唯一实例对象,都在类加载的时候先创建出来
    private static final HungrySingleton instance = new HungrySingleton();
    /**
     * 私有化的构造器
     */
    private HungrySingleton() {
    }
    /**
     * 获取该类唯一实例对象的静态方法
     * @return
     */
    public static HungrySingleton getInstance() {
        return instance;
    }
}


原文地址:https://blog.csdn.net/weixin_54851039/article/details/142957777

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!