Java - 自定义的 NotSerializableException class

Java - NotSerializableException on custom class

我在 Java 中有此代码(抱歉,如果我使用了一些西班牙语术语)。一切正常,直到我需要用 ObjectOutputStream 在文件中写一个对象,当 printStackTracejava.io.NotSerializableException.

代码是这样的。

package agenda;
import java.io.*;

public class Agenda implements java.io.Serializable {

    public static void addContact() {

        String nom, ap1, ap2, tf, em;

        Contact newContact = new Contact("Nombre", "Apellido", "Apellido 2", "Telefono", "Email");

        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("agenda.pzs", true)) {
            oos.writeObject(newContact); // NetBeans says the error is here

        } catch (IOException ex) {
            ex.printStackTrace(); // This is provisional only
            System.out.println("Ocurrió un error inesperado.");
        } 
    }

抱歉我的英语不好。

public class Agenda implements java.io.Serializable {

    public static void addContact() {

    String nom, ap1, ap2, tf, em;

    Contact newContact = new Contact("Nombre", "Apellido", "Apellido 2", "Telefono", "Email");

    try {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("agenda.txt",true));
            oos.writeObject(newContact);
            oos.close();            

    } catch (IOException ex) {
        ex.printStackTrace(); 
        System.out.println("Ocurrió un error inesperado.");
    } 

    }
}

你的括号有误

并在 Contact class

中实现 Serializable 接口

Serializable class 中的所有对象都必须是 Serializable。此要求是可遍历的 - 下面的所有对象也必须是可序列化的..

但是... 假设 Contact 是第三方 class 或者您出于任何其他原因不允许修改它,这是可能的解决方案:

免责声明:这很棘手,如果您不了解 "Contact" class 可能会导致许多意外问题。您必须确保您能够使用可序列化块 read/write "Contact" class 的状态。必须跟踪 Contact 实现中的任何更改。您需要一组 JUnit 测试来验证包装器是否正确。

进入正题: 创建 ContactWrapper class,它将在 write() 和 assemble this class 上从块中 disassemble "Contact" class 序列化 class在读取()期间。大致是这样的:

import static org.junit.Assert.*;

import java.io.*;

import org.junit.Test;

public class Agenda {

@Test
public void addContact() throws ClassNotFoundException, FileNotFoundException, IOException {

    String nom, ap1, ap2, tf, em;

     Contact newContact = new Contact("Nombre", "Apellido", "Apellido 2", "Telefono", "Email");

     ContactWrapper wrapper = new ContactWrapper();
     wrapper.setContact(newContact);

     ObjectOutputStream oos = null;
    try {
        oos = new ObjectOutputStream(new FileOutputStream("agenda.pzs"));
        oos.writeObject(wrapper);
    } finally{
       if(oos != null){ 
           oos.close();
       }
    }

    ObjectInputStream ois =  null;
    ContactWrapper wrapper_new = null;
    try{
        ois = new ObjectInputStream(new FileInputStream("agenda.pzs"));
        wrapper_new = (ContactWrapper) ois.readObject();
    } finally {
        if(ois != null)
            ois.close();
    }
    assertTrue(wrapper.equals(wrapper_new));

    Contact deserializedContact = wrapper.getContact();
    //Assuming that contact has corectly implemented equals()...
    assertTrue(newContact.equals(deserializedContact));

}
}

============================================= ===

import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;

public class ContactWrapper implements Serializable{
//assume not nulls here...-->equals
private String nom, ap1, ap2, tf, em;

public ContactWrapper(){

}

public void setContact(Contact contact){
  //Get State of "Contact" and write it to Serializable objects
  nom = contact.getNom();
  ap1 = contact.getAp1();
  //etc....
}

public Contact getContact(){
    //create Contact from serialized objects
    return new Contact(nom, ap1, ap2, tf, em);
}

private void writeObject(java.io.ObjectOutputStream out)
        throws IOException{
    System.out.println("write");
    out.writeObject(nom);
    out.writeObject(ap1);
    out.writeObject(ap2);
    out.writeObject(tf);
    out.writeObject(em);

}

    private void readObject(java.io.ObjectInputStream in)
        throws IOException, ClassNotFoundException{
        System.out.println("read");   
        nom = (String) in.readObject();
        ap1 = (String) in.readObject();
        ap2 = (String) in.readObject();
        tf = (String) in.readObject();
        em = (String) in.readObject();

    }

    private void readObjectNoData()
        throws ObjectStreamException{
        System.out.println("readNoData");
        //set everything to null?
    }

    @Override
    public boolean equals(Object other) {
        if(this == other) return true;
        if(other instanceof ContactWrapper){
            ContactWrapper that = (ContactWrapper)other;
            if(this.nom.equals(that.nom) &&
                    this.ap1.equals(that.ap1)
                    //...etc etc
                    ){
                return true;
            }
        }
        return false;
    }
}

编辑: 资料来源:http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html