当前位置 > it书童 > java > 正文

枚举实现单例模式

java it书童 2020-12-27 08:11:09 0赞 0踩 94阅读 0评论

枚举可能是实现单例的最佳方式

public enum EnumInstance {
    INSTANCE;
    private Object data;

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public static EnumInstance getInstance() {
        return INSTANCE;
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        EnumInstance instance = EnumInstance.getInstance();
        instance.setData(new Object());
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton_file"));
        oos.writeObject(instance);

        File file = new File("singleton_file");
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));

        EnumInstance newInstance = (EnumInstance) ois.readObject();
        System.out.println(instance.getData());
        System.out.println(newInstance.getData());
        System.out.println(instance.getData() == newInstance.getData());
    }
}
java.lang.Object@7291c18f
java.lang.Object@7291c18f
true

以上说明枚举类扛过了序列化破坏

这时,反射蠢蠢欲动,要来试下

public static void main(String[] args) throws Exception {
    Class<EnumInstance> objectClass = EnumInstance.class;
    Constructor<EnumInstance> constructor = objectClass.getDeclaredConstructor();
    // 通过反射,将权限打开
    constructor.setAccessible(true);
}

直接报异常 NoSuchMethodException,无法获取枚举类的无参构造器

反射踩到铁钉子了,由此可见,枚举类天然地不惧序列化以及反射破坏

查看 Enum 源码,发现其只有一个构造器

protected Enum(String name, int ordinal) {
    this.name = name;
    this.ordinal = ordinal;
}

反射贼心不死,继续在犯罪的边缘试探,直接拿带参构造器来处理

public static void main(String[] args) throws Exception {
    Class<EnumInstance> objectClass = EnumInstance.class;
    Constructor<EnumInstance> constructor = objectClass.getDeclaredConstructor(String.class, int.class);
    // 通过反射,将权限打开
    constructor.setAccessible(true);
    EnumInstance enumInstance = constructor.newInstance("Geely", 66);
}

执行,继续报错:

这下就真的 GG 了,你再牛,也牛不过 jdk 的规定吧

关于我
一个文科出身的程序员,追求做个有趣的人,传播有价值的知识,微信公众号主要分享读书思考心得,不会有代码类文章,非程序员的同学请放心订阅
转载须注明出处:https://www.itshutong.com/articles/1014