3

我正在尝试使用 WriteObject 方法编写 pojo 类的实例。当我写这样的代码时:

    private void writeObject(ObjectOutputStream oos) throws IOException,ClassNotFoundException{ 
    oos.defaultWriteObject();    
    oos.writeObject(this);
}

它工作正常,但是当我尝试创建一个新的本地对象并将其传递给 writeObject 方法时,它失败了

线程“主”java.lang.StackOverflowError 中的异常

有人可以解释一下为什么它会一遍又一遍地递归调用 writeObject 方法吗?

class Employee implements Serializable{
    private String name;
    private int age;
    private void readObject(ObjectInputStream ois) throws IOException,ClassNotFoundException{
        ois.defaultReadObject();
        Employee emp = (Employee)ois.readObject();
        emp.toString();
    }
    private void writeObject(ObjectOutputStream oos) throws IOException,ClassNotFoundException{
        oos.defaultWriteObject();
        Employee emp = new Employee("sumit",10);
        oos.writeObject(emp);
    }
    public Employee(){

    }
    public Employee(String name, int age){
        this.name = name;
        this.age = age;
    }   
}
4

2 回答 2

0

这里发生的是“Employee”类是可序列化的。并且您已经在其中覆盖writeObject了方法。

现在在此方法overridden中,您再次创建Employee对象实例并调用.writeObjectoos

序列化逻辑检查所添加的对象是否可序列化。如果是,则对其进行序列化,否则抛出NotSerializable异常。

在这里,要添加的对象是Serializable。因此它去序列化它并发现它Object已经writeObject覆盖了方法。所以它调用那个方法。

现在它再次进入您覆盖的方法逻辑并再次调用相同的方法

oos.defaultWriteObject(); 
Employee emp = new Employee("sumit",10); 
oos.writeObject(emp);

并且循环继续,导致StackOverflow错误,因为它一遍又一遍地递归调用它而不会中断

于 2018-08-23T06:03:18.327 回答
0

这是因为您writeObject在类中覆盖了方法Employee。因此,当您创建Employee对象并尝试使用writeObject方法编写它时,它会被递归调用,从而导致StackOverflow错误。

但是,当您不编写Employee对象时,代码会正确执行。

---根据评论中要求的澄清进行编辑

在您的Employee类中,您正在重写writeObjectmethod ,因此,无论何时,您尝试ObjectOutputStream.writeObject使用Employeeas 参数调用时,都会调用您重写的方法。现在,在您writeObjectEmployee类中被覆盖的情况下,您再次 以 Employee 作为参数调用ObjectOutputStream.writeObject( ),因此,类的方法被递归调用(每次都使用新的 Employee 对象)并且您得到stackoverflow错误。oos.writeObject(emp);writeObjectEmployee

现在,如果您尝试调用递归this关键字,那是因为您尝试ObjectOutputStream.writeObject使用相同的Employee类实例进行调用。根据ObjectOutputStream.writeObject下面提到的链接中的文档:

https://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html

对单个对象的多个引用使用引用共享机制进行编码,以便对象的图形可以恢复到与原始对象相同的形状。

事实上,如果您在 main 方法中尝试以下代码:

Employee emp = new Employee("sumit",10);
oos.writeObject(emp);
oos.writeObject(emp);

即,如果您writeObject在同一个对象上多次调用,它只会被调用一次。

于 2018-08-23T07:05:44.117 回答