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