性男女做视频网站,怎么建自己的平台,怎么用安卓机顶盒做网站服务器,个人网站开发协议原因分析
1.反序列化方法
① jdk8中的Enum源码中对反序列化方法进行重写#xff0c;抛出异常。 java.lang.Enum#readObject方法截图如下 ②java.io.ObjectInputStream#readObject 方法中的 readEnum 方法处理了枚举类型的反序列化#xff0c;从而确保了枚举的单例特性。
…原因分析
1.反序列化方法
① jdk8中的Enum源码中对反序列化方法进行重写抛出异常。 java.lang.Enum#readObject方法截图如下 ②java.io.ObjectInputStream#readObject 方法中的 readEnum 方法处理了枚举类型的反序列化从而确保了枚举的单例特性。
具体来说在 Java 的序列化过程中当对象被反序列化时ObjectInputStream 类会调用 readObject 方法来读取对象。对于枚举类型readObject 方法会调用 readEnum后者会根据枚举的类型和名称来查找已经存在的枚举常量Enum.valueOf()。
java.io.ObjectInputStream#readObject方法截图如下 java.io.ObjectInputStream#readEnum方法截图如下,包含Enum.valueOf() 这一过程确保了以下几点 确保单例性readEnum 方法通过调用 Enum.valueOf() 来查找与名称匹配的枚举常量这意味着无论你如何尝试反序列化得到的都是已经存在的枚举实例保证了枚举的单例特性。 防止实例创建由于枚举的构造函数是私有的而且在反序列化过程中不会直接调用构造函数因此无法创建新的枚举实例。
2.反射newInstance()方法
在 Java 中使用反射的 java.lang.reflect.Constructor#newInstance 方法来创建枚举类的实例时会进行特殊的检查。
如果尝试通过反射调用 newInstance 方法来创建一个枚举类型的实例Java 会抛出 IllegalArgumentException并指出 Cannot reflectively create enum objects。这一设计是为了保护枚举类型确保它们的实例唯一性。
如下代码 枚举在 Java 中被设计为单例每一个枚举常量在一个应用程序的生命周期中只能存在一个实例。由于枚举常量在定义时就已经实例化Java 不允许通过反射来创造额外的枚举实例。这一机制通过阻止反射创建枚举对象进一步增强了枚举的安全性和一致性。
因此结合 ObjectInputStream 在反序列化时对枚举类型的特殊处理和反射机制的限制共同保证了枚举类型不会被意外或者恶意地创建多个实例。 Enum的反编译
Enum 类型的静态初始化static
枚举类在类加载时会静态初始化并创建实例这一过程是由 JVM 保证的。因此枚举类型的实例是在类加载时就已经创建好了而反序列化时只是获取这个已存在的实例。这种机制避免了创建多个枚举实例的风险。 枚举的反编译属性都有static修饰。 单例模式示例
假设有一个简单的枚举单例类
import java.io.Serializable;public enum Singleton implements Serializable {INSTANCE;public void someMethod() {System.out.println(This is a method in the Singleton instance.);}
}反射攻击与反序列化攻击 通常在实现单例模式时使用反射可以绕过单例的构造方法从而创建多个实例。而反序列化攻击则是通过反序列化创建新实例绕过单例的构造过程。 有人说枚举单例不会被破坏是因为 普通类的反序列化使用了unsafe枚举没有使用。 在 Java 中反序列化的过程是为了将序列化的字节流转换回对象。为了提高性能Java 的反序列化机制使用了 Unsafe 类来直接操作内存。普通类的反序列化可能会涉及到创建新的对象实例这时使用 Unsafe 可以避免调用构造函数从而提高效率。
然而对于枚举类来说Java 语言设计上已经保证了枚举实例是唯一的即单例的。在反序列化过程中枚举的实例是通过 Enum.valueOf() 方法进行查找的这个方法会在枚举值唯一的情况下返回已存在的实例而不是创建新的实例。
如有说错的地方请大家及时指出以免误导他人 参考
你知道吗枚举单例模式是世界上最好的单例模式-CSDN博客