如何避免使用反射创建新实例



我有一个Singleton类,它是通过按需持有者初始化实现的。根据这篇文章,它仍然容易受到反思攻击。

如何防止java反射调用私有构造函数并创建新实例

这是我的SingletonTest类:

class SingletonTest{
    public SingletonTest(){
        System.out.println("before SingletonTest()");
        Singleton s1 = Singleton.getSingleton();
        Singleton s2 = Singleton.getSingleton();
        System.out.printf("s1 Hash: %dn",System.identityHashCode(s1));
        System.out.printf("s2 Hash: %dn",System.identityHashCode(s2));
        Constructor<?> con = Singleton.class.getDeclaredConstructors()[1];
        con.setAccessible(true);
        //System.out.println(con.toString());
        try {
            Singleton s3 = (Singleton) con.newInstance();
            System.out.printf("s3 Hash: %dn",System.identityHashCode(s3));
        } catch (Exception ex) {
           ex.printStackTrace();
        }
        System.out.println("after SingletonTest()");
    }
    public static void main(String[] args){
        new SingletonTest();
    }
}

这是我的Singleton类:

final public class Singleton {
    private Singleton(){
        System.out.println("Singleton created...!");
    }
    public static Singleton getSingleton(){
        return SingletonHolder.INSTANCE;
    }
    static class SingletonHolder{
            private static final Singleton INSTANCE = new Singleton();
    }
    public void doStuff(){
        System.out.println("dostuff....");
    }
}

输出:

before SingletonTest()
Singleton created...!
s1 Hash: 1924489565
s2 Hash: 1924489565
Singleton created...!
s3 Hash: 294316734
after SingletonTest()

在构造函数中检查并抛出异常如何?

private Singleton(){
    if(SingletonHolder.INSTANCE !=null)
       throw new IllegalStateException("Not allowed!");
}

另一种可能性是,使用javaEnum实现您的singleton模式。

public enum Singleton {
    INSTANCE;
    public void doStuff(){...}
}

相关内容

  • 没有找到相关文章

最新更新