mercredi 7 octobre 2015

Singleton can always be reflected(Reflection even enum)

I have this simple enum that serves as a Singleton provider for an Object type object

package package2;

public enum SingletonEnum {

    INSTANCE;
    private Object obj = new Object();

    public Object getObject() {
        return obj;
    }
}

And i have this Sample main that reflects the field instance, modify the field by assigning a new object

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());
    }
}

the output is

1554514352

2112239710

two different hashcodes where displayed, and I assume that two references were made. how come this possible? I thought enum Singletons are the only way to make Singleton "Singleton" and cannot be reflected, so this only means that only SecurityManager can prohibit all reflections. so my question is.. "WHAT" is the most safest way to prohibit an instantiation of a Singleton object?





Aucun commentaire:

Enregistrer un commentaire