单身总是可以被反射(反射甚至枚举)

时间:2015-10-07 08:25:29

标签: java reflection enums singleton

我有这个简单的枚举,作为Object类型对象的单例提供者

package package2;

public enum SingletonEnum {

    INSTANCE;
    private Object obj = new Object();

    public Object getObject() {
        return obj;
    }
}

我有这个反映字段实例的Sample main,通过分配一个新对象来修改字段

package package2;

import java.lang.reflect.Field;

public class Sample2 {

public static void main(String[] args) {

    Object obj = SingletonEnum.INSTANCE.getObject();
    System.out.println(obj.hashCode());

    try {
        Class<?> clazz = Class.forName("package2.SingletonEnum");
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {

            if (field.getType().equals(Object.class)) {

                field.setAccessible(true);
                field.set(SingletonEnum.INSTANCE, new Object());
            }
        }
    } 
    catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
    catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
    catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 

        System.out.println(SingletonEnum.INSTANCE.getObject().hashCode());
    }
}

输出

1554514352

2112239710

显示了两个不同的哈希码,我假设有两个引用。怎么可能呢?我认为enum Singletons是制作Singleton&#34; Singleton&#34;的唯一途径。并且无法反映,因此这仅表示只有SecurityManager才能禁止所有反射。所以我的问题是......&#34;什么&#34;是禁止实例化Singleton对象最安全的方法吗?

1 个答案:

答案 0 :(得分:0)

Singleton意味着只能有一个类的实例。这适用于static class Adapter extends FragmentStatePagerAdapter { public Adapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { Fragment fragment=null; switch (position) { case 0: fragment=MainListFragment.newInstance(mConnected, "Notices"); //don't forget to save mConnected in savedInstanceState case 1: fragment=MainListFragment.newInstance(mConnected, "Posts"); } return fragment; } @Override public int getCount() { return 2; } @Override public CharSequence getPageTitle(int position) { String title=""; switch (position) { case 0: title="Notices"; case 1: title="Posts"; } return title; } 。这并不意味着实例是不可变的。您正在更改单例的SingletonEnum成员,从而导致不同的hashCodes。 在这种情况下你可以做的是定义最终的对象,所以它不能被改变,尽管它必须被初始化。

obj