- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在阅读Effective Java Item74。我对java对象的序列化很感兴趣。但一种方法“readObjectNoData”让我感到困惑。
这里是JavaDoc的解释
For serializable objects, the readObjectNoData method allows a class to control the initialization of its own fields in the event that a subclass instance is deserialized and the serialization stream does not list the class in question as a superclass of the deserialized object. This may occur in cases where the receiving party uses a different version of the deserialized instance's class than the sending party, and the receiver's version extends classes that are not extended by the sender's version. This may also occur if the serialization stream has been tampered; hence, readObjectNoData is useful for initializing deserialized objects properly despite a "hostile" or incomplete source stream.
它说当我序列化一个对象时,它是旧版本,不会扩展父类,但是当我反序列化时,该类升级到新版本并扩展其他一些类。
我真的很想玩这个。所以我有一个 Employee 类
public class Employee implements Serializable { //v1
public String name;
public int age;
protected String address;
static final long serialVersionUID = 1L;
public Employee()
{
name= "John";
age = 1;
address ="N/A";
}
public Employee(String name , int age, String address)
{
this.name = name;
this.age = age;
this.address = address;
}
}
还有一个序列化类
public class Se {
public static void main(String [] args) {
Employee e = new Employee();
try {
FileOutputStream fileOut =
new FileOutputStream("tmp.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in tmp.txt");
}catch(IOException i) {
i.printStackTrace();
}
}
}
将 Employee 对象序列化到 tmp.txt 后,我更改了 Employee 类
public class Employee extends Person { //v2
protected String address ;
static final long serialVersionUID = 1L;
public Employee()
{
super();
address ="N/A";
}
public Employee(String name , int age, String address)
{
super(name,age);
this.address = address;
}
private void readObjectNoData() throws ObjectStreamException {
name = "John";
age = 1;
}
}
这是我的 Person 类
class Person implements Serializable{
protected String name;
protected int age;
Person() {
this("John",1);
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
当我通过反序列化类进行反序列化时
public class De {
public static void main(String [] args) {
Employee e = null;
try {
FileInputStream fileIn = new FileInputStream("tmp.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i) {
i.printStackTrace();
System.out.println("IOException");
return;
}catch(ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("Age: " + e.age);
}
}
输出始终显示
Deserialized Employee...
Name: null
Address: N/A
Age: 0
即使我在 readObjectNoData 方法中设置调试点,它也永远不会被触发,我在网上找不到任何可运行的示例,所以我在这里提供了很多代码。有谁知道我错过了什么?
如有任何意见,我们将不胜感激。
最佳答案
这是一种独特的情况,其中类的反序列化器具有基于子类(Person)的类(Employee)版本。
子类可以说“如果我的基类不在序列化数据中也没关系 - 只需创建一个空基类即可。
Edit below
尝试这两个版本的“反序列化”。我的意思是序列化您的 v1 员工,然后尝试以下操作:
import java.io.Serializable;
public class Employee extends Person implements Serializable { //v2
protected String address ;
static final long serialVersionUID = 1L;
public Employee()
{
super();
address ="N/A";
}
public Employee(String name , int age, String address)
{
super(name,age);
this.address = address;
}
}
Person
import java.io.ObjectStreamException;
import java.io.Serializable;
class Person implements Serializable{
protected String name;
protected int age;
Person() {
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
private void readObjectNoData() throws ObjectStreamException {
name = "cccc";
age = 1;
throw new IllegalArgumentException();
}
}
您将看到一个异常
Exception in thread "main" java.lang.IllegalArgumentException
at test.serialization.Person.readObjectNoData(Person.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObjectNoData(ObjectStreamClass.java:1089)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1955)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1808)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at test.serialization.De.main(De.java:22)
希望有帮助
关于java - readObjectNoData 何时被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46481605/
我正在阅读Effective Java Item74。我对java对象的序列化很感兴趣。但一种方法“readObjectNoData”让我感到困惑。 这里是JavaDoc的解释 For seriali
我正在阅读Effective Java中的序列化章节。我正在尝试理解书中的以下段落。 If you implement a class with instance fields that is ser
在序列化/反序列化过程中,我们可以定义readObjectNoData()/writeReplace()/readResolve()来自定义默认的序列化/反序列化行为。 现在我的问题是声明在哪里?像
我是一名优秀的程序员,十分优秀!