用其他方法破解单例

用其他方法破解单例,第1张

用其他方法破解单例

我可以想到的三种方法是:

序列化

如果您的单例类是可序列化的,则可以序列化它的一个实例,然后反序列化它,以获得该类的第二个对象。

您可以通过实现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());


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5600727.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存