java中使用private构造方法不能实现单例模式

int32位 posted @ Sep 09, 2014 10:52:39 AM in java , 1682 阅读
转载请注明:http://krystism.is-programmer.com/若有错误,请多多指正,谢谢!

众所周知,一般使用java实现单例模式有两种方法,分别为急切式(饥饿式)和双重加锁式,急切式就是在声明时即创建,这样在类加载时就已经创建好了,即时我们可能并不不需要它,它的生命周期是永久的,造成内存泄漏的可能!第二种方式是lazy的,只有在使用时创建,实现了延迟加载。代码为

1.急切式

class Singleton {
    private final static Singleton instance = new Singleton();
    private Singleton(){
    }
    public static Singleton getInstance() {
        return instance;
    }
}

2. 双重加锁式

class Singleton {
    private volatile static Singleton instance = null;
    private Singleton(){

    }
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

还有一种方法是使用内部类的方法,这主要为克服方法1中的问题,既能实现延迟加载,又能保证线程安全,而且性能不错。代码为:

class Singleton {
    private Singleton() {

    }
    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
}

以上方法都是通过使用private构造方法来阻止外部直接创建对象,但如果使用反射机制,则不能保证实例的唯一性了!!!

public class SingletonDemo {
    //@SuppressWarnings("unchecked")
    //public static <T> T newInstance(Class<?> cl) {
    //    T t = null;
    //    try {
    //        t = (T)cl.newInstance(); /* 只能调用public构造方法 */
    //    } catch(Exception e) {
    //        e.printStackTrace();
    //    }
    //    return t;
    //}
    @SuppressWarnings("unchecked")
    public static <T> T newInstance(Class<?> cl) {
        T t = null;
        try {
            Constructor<?> constructor = cl.getDeclaredConstructor();
            constructor.setAccessible(true);
            t = (T)constructor.newInstance();
        } catch(Exception e) {
            e.printStackTrace();
        }
        return t;
    }
    @SuppressWarnings("unchecked")
    public static <T> T newInstance(Class<?> cl, Class<?>...args) {
        T t = null;
        try {
            Constructor<?> constructor = cl.getDeclaredConstructor(args);
            constructor.setAccessible(true);
            t = (T)constructor.newInstance("name", 1);
        } catch(Exception e) {
            e.printStackTrace();
        }
        return t;
    }
    public static void main(String[] args) {
        Singleton instance = Single.INSTANCE;
        Singleton s1 = newInstance(Singleton.class, String.class, int.class);
        Singleton s2 = newInstance(Singleton.class, String.class, int.class);
        //Tmp t1 = newInstance(Tmp.class);
        //Tmp t2 = newInstance(Tmp.class);
        //System.out.println(s1 == s2);
        //System.out.println(t1 == t2);
    }
}

Joshua Bloch (Effect java 作者)提出一种新的方法实现单例模式,就是使用Enum(其实也是类,一种特殊的类,构造方法必须是private ,final的)!如下:

 

enum Singleton {
    INSTANCE;
    public void sayHi() {
        System.out.println("Hi");
    }
}

这样当试图通过反射机制创建对象时,会抛出异常!

转载请注明:http://krystism.is-programmer.com/若有错误,请多多指正,谢谢!
  • 无匹配
  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter