我可以想到的三种方法是:
序列化如果您的单例类是可序列化的,则可以序列化它的一个实例,然后反序列化它,以获得该类的第二个对象。
您可以通过实现readResolve方法来避免这种情况。
类加载public class Singleton implements Serializable { private static final Singleton INSTANCE = new Singleton(); public static Singleton getInstance(){ return INSTANCE; } public Object readResolve() throws ObjectStreamException { return INSTANCE; //ensure singleton is returned upon deserialization. }}
可以由两个不同的类加载器加载同一个类,这样,您可以通过
getInstance在两个不同的类加载器加载的类中简单地调用其方法来创建单例类的两个实例。这种方法将有效,
而不必诉诸于私有构造函数 。
反射ClassLoader cl1 = new URLClassLoader(new URL[]{"singleton.jar"}, null);ClassLoader cl2 = new URLClassLoader(new URL[]{"singleton.jar"}, null);Class<?> singClass1 = cl1.loadClass("hacking.Singleton");Class<?> singClass2 = cl2.loadClass("hacking.Singleton");//...Method getInstance1 = singClass1.getDeclaredMethod("getInstance", ...);Method getInstance2 = singClass2.getDeclaredMethod("getInstance", ...);//...Object singleton1 = getInstance1.invoke(null);Object singleton2 = getInstance2.invoke(null);
如您所指出的,通过反射,您可以创建该类的两个实例。我认为前面的示例只是该方法的一种变体。但是我相信您可以使用来防止这两种情况的发生
SecurityManager。
System.setSecurityManager(new SecurityManager());
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)