参见英文答案 > Is custom enum Serializable too? 3个
我一直在搜索web以查找与java中的枚举类相关的一些查询的答案.
我的查询是为什么在枚举类中阻止了默认的反序列化.我可以看到enum类实现了Serializable接口,但它也有2个方法如下 –
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
}
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
看完这堂课后我更加困惑.任何帮助将不胜感激.提前致谢.
我更困惑,因为ENUM实现了可序列化的接口本身,并且上面的方法也抛出“抛出新的InvalidObjectException(”不能反序列化枚举“);”例外.所以我没有清楚地了解上述两种方法的用途?
另外对上述两种方法的评论说“防止默认反序列化”是什么意思?
解决方法:
枚举值是可序列化的 – 这就是通过实现Serializable接口所声明的全部内容.
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Dummy {
public enum Color {
RED, GREEN, BLUE
}
public static void main(String[] args) throws Exception {
System.out.println(deserialize(serialize(Color.GREEN), Color.class));
}
private static T deserialize(byte[] data, Class cls) throws IOException, ClassNotFoundException {
try (final ByteArrayInputStream stream = new ByteArrayInputStream(data);
final ObjectInputStream reader = new ObjectInputStream(stream)) {
return cls.cast(reader.readObject());
}
}
private static byte[] serialize(Serializable obj) throws IOException {
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
try (final ObjectOutputStream writer = new ObjectOutputStream(stream)) {
writer.writeObject(obj);
}
} finally {
stream.close();
}
return stream.toByteArray();
}
}
但是,由于枚举常量的特殊性,运行时不能使用默认的序列化机制,因为这将允许构造给定常量的多个值,违反保证,枚举常量是单例.
因此,运行时使用“非默认”机制来序列化/反序列化枚举常量,从而确保单例属性.通过覆盖readObject来解除默认机制只是一种安全措施,它可以确保您不会通过对反序列化恶意攻击的字节流来欺骗VM来创建新的常量.
TL; DR枚举常量完全(可)序列化,如基类Enum实现Serializable接口所声称的那样.但是,在内部,VM /运行时特别处理序列化,并禁用这些类型对象的默认机制.
标签:java,enums,serialization
来源: https://codeday.me/bug/20190528/1168090.html