枚举类型的单例模式
?
目前单例模式有三种形式
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的单例是最安全的,其它两种方式都可以用反射得到
?