第3条:用私有构造器或者枚举类型强化Singleton属性

Singleton是指被实例化一次的类,通常表示无状态的对象,如函数。为啥要强调Singleton属性,说的更直白一点就是Singleton属性有啥好处:

  1. 节省内存:由于Singleton模式限制一个类只能创建一个实例,它有助于减少应用程序在运行过程中所需的内存消耗。这对于性能优化和资源受限的环境尤其重要。
  2. 统一管理:Singleton模式可以作为一个状态仓库,为系统中的其他部分提供一致的状态信息或服务。例如,它可以用于跟踪应用程序范围内的计数器或配置信息,保证数据的一致性和准确性。
  3. 全局访问点:通过Singleton模式提供的全局访问点,可以在应用程序的任何地方方便地访问该唯一实例。这简化了不同组件之间的交互,因为它们都可以通过同一个访问点来获取所需的服务或数据。
  4. 避免资源的多重占用:在处理如文件系统、数据库连接等共享资源时,使用Singleton可以避免资源的多重占用和竞争条件,从而确保资源的有效利用和管理。
  5. 控制实例化过程:Singleton模式允许类自行控制其唯一实例的创建过程,这有助于实现懒加载(延迟初始化)和同步创建实例的功能,特别是在多线程环境中。
  6. 保护敏感信息:如果类包含敏感信息或关键资源,Singleton模式可以防止未经授权的访问和实例化,从而提高应用程序的安全性。
  7. 方便的配置管理:在复杂的系统中,使用Singleton可以简化配置管理。例如,服务器程序中的配置信息可以由一个Singleton对象统一读取和管理,其他对象可以通过这个单例对象获取这些配置信息,而无需直接访问配置文件。

有两种常见实现Singleton的方式,原理都是将构造器设置为私有,通过导出一个公有静态成员来提供对唯一实例的访问。

1.用final字段作为这个公有静态的成员

public class Person {
    private String name;
    private Integer age;

    // 使用public final 字段singleton
    public static final Person INSTANCE =new Person("张三",80);


    private Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {
        Person instance = Person.INSTANCE;
        System.out.println(instance.name);
        System.out.println(instance.age);
    }
}
C:\soft\JDK21\bin\java.exe "-javaagent:C:\soft\idea\IntelliJ IDEA 
张三
80

Process finished with exit code 0

2.提供一个静态工厂方法作为这个公有成员

public class Person {
    private String name;
    private Integer age;

    
    private static final Person INSTANCE =new Person("张三",80);
    private Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    // 使用静态工厂的singleton
    public static Person getInstance() {
        return INSTANCE;
    }

    public static void main(String[] args) {
        Person instance = Person.getInstance();
        System.out.println(instance.name);
        System.out.println(instance.age);
    }
}
张三
80

Process finished with exit code 0

第二种方式其实就是第一种方式的变形形式,第一种方式主要优点是,API可以清楚的表明该类是个singleton;公有的静态字段是final的,因此永远包含同一个对象的引用。第二个有点是它更简单(tips:个人不觉得)

如果要使其singleton序列化仅仅implements Serializable是不行的,还要提供一个readResolve方法。

3.用枚举实现singleton-首选方法:

public enum Person {

    张三;
    
    public static void main(String[] args) {
        Person instance = Person.张三;
        System.out.println(instance);
    }
}
张三

Process finished with exit code 0

这种方式更为简洁,而且自带序列化,反射攻击也不用担心,枚举类型是实现singleton最佳的方式。

Tips:所有内容开源且不追加任何条件,看完后觉得内容不错,点个赞不为过吧!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值