目前单例模式有三种形式
1、提供一个静态的公共属性
2、提供一个静态的公共方法
3、enum类型的(这个是针对jdk 1.5以及1.5版本以上的)
enum SingletonExample {
INSTANCE;
public static SingletonExample getInstance() {
return INSTANCE;
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class EnumTest {
public static void singletonTest() throws IllegalArgumentException, InstantiationException,
IllegalAccessException, InvocationTargetException {
try {
//得到第一个实例
SingletonExample s = SingletonExample.getInstance();
//用反射得到第二个实例,这里引用类的时候得写全路径,否则会报找不到类
Class c = Class.forName("com.wush.singleton.SingletonExample");
//getDeclaredConstructors返回 Constructor 对象的一个数组,
//这些对象反映此 Class 对象表示的类声明的所有构造方法。
//它们是公共、保护、默认(包)访问和私有构造方法。
//返回数组中的元素没有排序,也没有任何特定的顺序。
//如果该类存在一个默认构造方法,则它包含在返回的数组中。
//如果此 Class 对象表示一个接口、一个基本类型、一个数组类或 void,
//则此方法返回一个长度为 0 的数组
Constructor[] con = c.getDeclaredConstructors();
Constructor conc = con[0];
//setAccessible将此对象的 accessible 标志设置为指示的布尔值。
//值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
//值为 false 则指示反射的对象应该实施 Java 语言访问检查。
conc.setAccessible(true);
SingletonExample ss = (SingletonExample)conc.newInstance();
System.out.println(s+"/"+ss);
System.out.println(s==ss);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IllegalArgumentException,
InstantiationException, IllegalAccessException, InvocationTargetException {
singletonTest();
}
}
结果如下
Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects
at java.lang.reflect.Constructor.newInstance(Constructor.java:492)
at com.test.EnumTest.singletonTest(EnumTest.java:26)
at com.test.EnumTest.main(EnumTest.java:34)
从结果可以看出用enum的单例是最安全的,其它两种方式都可以用反射得到
分享到:
相关推荐
为了解决这个问题,Java引入了枚举类型来实现单例模式,这是一种简洁且线程安全的方法。 枚举在Java中是特殊的类,由JVM自动管理,保证了线程安全。当枚举类被加载时,JVM会自动初始化所有的枚举实例,因此在多线程...
JAVA 枚举单例模式是一种特殊的单例模式实现方式,它使用枚举类型来保证线程安全、防止序列化问题和反射攻击。下面我们将详细解释这个模式的实现原理和源码分析。 线程安全 在 Java 中,枚举类型的实例是在类加载...
此外,单例模式还有几种变体,比如静态内部类单例和枚举单例。静态内部类单例利用Java类加载机制保证了线程安全,而枚举单例则是Java中实现单例的最佳方式,因为它天然支持序列化且防止反射攻击。 在代码实现上,...
本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)...进阶篇有反射、泛型、注解、网络编程、多线程、序列化、数据库、Servlet、JSP、XML解析、单例模式与枚举。本专栏主要为Java入门者提供实验参考。
将单例定义为一个枚举类型,这样不仅能保证线程安全,还能防止反射攻击。枚举是JVM的固有特性,因此它的创建是线程安全的,并且不允许实例化多个枚举实例。 每种实现方式都有其优缺点,选择哪种方式取决于特定的...
在Java中,实现单例模式有多种方法,包括懒汉式(线程不安全)、饿汉式(静态常量)、双检锁(DCL)和枚举单例。其中,双检锁和枚举单例是线程安全的,推荐在多线程环境下使用。 ```java // 双检锁/双重校验锁(DCL...
5. **枚举单例**:利用枚举类型实现单例模式。 - 优点:简洁高效,线程安全,延迟加载。 - 缺点:使用场景受限。 #### 四、单例模式的复杂性 在实际应用中,单例模式可能还会面临更复杂的情况,例如: 1. **DCL...
单例模式是软件设计模式中的一种,其核心思想是确保一个类在整个系统中只有一个实例存在。这在Java中尤其有用,因为多个实例可能导致资源浪费,比如内存占用过多,或者不同实例间的操作不一致。Java中的23种设计模式...
- **枚举方法**:通过枚举类型来隐藏类的构造函数,确保只有一个实例。 4. **注意事项** - 单例模式可能导致程序设计过于复杂,难以进行单元测试。 - 单例模式的实例在程序整个生命周期内存在,可能会导致资源...
5. **枚举类型**:Java枚举是天然的单例模式,既简单又安全。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { } } ``` 然而,单例模式并非总是完美的。它的缺点包括: - **测试...
在Java中实现单例模式有多种方法,包括懒汉式(线程不安全)、饿汉式(线程安全)、双重检查锁定(DCL,线程安全)以及枚举单例。确保单例模式正确实现的关键在于防止多线程环境下的多次实例化和序列化/反序列化时的...
此外,Java 5引入的枚举类型提供了一种简洁、线程安全且避免了反射攻击的单例实现方式: ```java public enum Singleton { INSTANCE; } ``` 单例模式虽然简单实用,但也存在一些缺点,如妨碍了继承、不支持多态...
Java中的枚举类型是线程安全的,并且只会装载一次,设计者充分考虑到了线程安全问题,因此使用枚举实现单例模式是一种简洁而且高效的解决方案。 6. 容器式单例(Singleton Holder) 通过一个私有的静态内部类...
除了上述三种单例模式外,在Java中还可以使用枚举类型来实现单例模式。Java枚举的特性保证了枚举类型的单例性,因为枚举实例是类加载时创建的,且Java虚拟机保证不会创建重复的实例。 单例模式在很多情况下都是很...
除了以上三种经典的实现方式,Java 1.5之后引入了枚举类型,也提供了一种更简洁且线程安全的单例实现方式。通过定义一个枚举类,其中包含一个枚举常量,这个枚举常量即为单例实例。这种方式既保证了线程安全,又避免...
使用枚举类型实现单例,既简单又线程安全,还能防止序列化破坏单例。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { // ... } } ``` 每种方法都有其优缺点。饿汉式虽然简单...
Java枚举类型天然支持单例模式,既简单又线程安全: ```java public enum SingletonClass { INSTANCE; // 可以添加方法 } ``` 这种方式简洁且易于理解和维护,是推荐的单例实现方式。 总之,单例模式通过限制类...
Java中的枚举类型是线程安全的,并且只会装载一次,设计者充分考虑了线程安全问题。因此,枚举的写法也是实现单例模式的最佳实践。 ## 单例模式可能遇到的问题 ### 反序列化破坏单例 当单例对象实现java.io....
将单例定义为枚举类型是一种简洁且线程安全的方式。Java枚举默认是线程安全的,而且防止了反射攻击。 ```java public enum Singleton { INSTANCE; public void whateverMethod() { } } ``` 7. **登记式/注册...
单例模式和多例模式是软件设计模式中的两种重要类型,它们主要用来控制类的实例化过程,确保在系统中某一类只有一个实例或者多个实例。 单例模式是一种限制类的实例化过程,使得一个类在整个应用程序中只能有一个...