简体   繁体   English

类实现Serializable时出现NotSerializableException

[英]NotSerializableException when classes implement Serializable

TL;DR TL; DR

I get a java.io.NotSerializableException when I try to de-serialize a PullSheet object (classes below). 当我尝试反序列化PullSheet对象(下面的类)时,出现java.io.NotSerializableException。 Where am I going wrong? 我要去哪里错了?

EDIT: After adding an empty constructor to the problem class I am now getting an "incompatible" exception. 编辑:将一个空的构造函数添加到问题类后,我现在得到一个“不兼容”异常。

StackTrace: 堆栈跟踪:

java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:606)
java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1772)
java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
com.campusden.learning.movingdata.ScannerActivity.loadSheet(ScannerActivity.java:271)
com.campusden.learning.movingdata.ScannerActivity.onCreate(ScannerActivity.java:79)
android.app.Activity.performCreate(Activity.java:6679)
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
android.app.ActivityThread.-wrap12(ActivityThread.java)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
android.os.Handler.dispatchMessage(Handler.java:102)
android.os.Looper.loop(Looper.java:154)
android.app.ActivityThread.main(ActivityThread.java:6119)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

The Problem 问题

I am trying to serialize a PullSheet object so that a simple backup of data is stored and as a functional requirement for users. 我正在尝试序列化PullSheet对象,以便存储简单的数据备份并作为用户的功能要求。 I am able to serialize the object without exception, but when I try to deserialize I get a java.io.NotSerializableException on the PullItem class. 我能够毫无例外地序列化对象,但是当我尝试反序列化时,我在PullItem类上得到了java.io.NotSerializableException。

The Code 编码

PullSheet.java PullSheet.java

import ...

public class PullSheet implements Serializable{

protected String pullerName;
protected String role;
protected String store;
protected String sheetId;
protected String runItId;
protected String date;
protected UUID uuid;
protected String serialName;
protected Long startTime = System.currentTimeMillis();
protected ArrayList<PullItem> SheetItems = new ArrayList<PullItem>();


public void createSheet(String _pullerName, String _role, String _store, String _runItId){
    setPullerName(_pullerName);
    setRole(_role);
    setStore(_store);
    setRunItId(_runItId);
    setSerialName();
    setDate();
    setUuid();
    setSheetId();
}

protected void addItem(String sku, Integer qty){
    SheetItems.add(new PullItem(sku, qty));
}
protected void removeItem(PullItem item){
    this.SheetItems.remove(item);
}

//Getters and setters

public String getPullerName(){ return pullerName; }
public String getRole(){ return role; }
public String getStore(){ return store; }
public String getRunItId(){ return runItId; }
public String getSheetId(){ return sheetId; }
public Long getStartTime(){ return startTime; }
public UUID getUuid() { return uuid; }


private void setPullerName(String _pullerName){ pullerName = _pullerName; }
private void setRole(String _role){ pullerName = _role; }
private void setStore(String _store){ store = _store; }
private void setRunItId(String _runItId){ runItId = _runItId; }
private void setSerialName(){ serialName = this.store + "-" + this.date + "_" + this.uuid; }
private void setUuid(){ uuid = UUID.randomUUID(); }
private void setDate() {
    SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
    this.date = formatter.format(new Date(this.startTime));
}

private void setSheetId(){

    String randUUID = uuid.toString();
    sheetId = this.date + "-" + this.store + "-" + this.pullerName + "-" + randUUID + "-" + this.runItId;

}

}

PullItem.java PullItem.java

import ...

public class PullItem implements Serializable {

protected String sku;
protected Integer qty;


public PullItem(String sku, Integer qty) {
    setSku(sku);
    setQty(qty);
}

public PullItem(String sku) {
    setSku(sku);
    this.qty = 1;
}


String getSku(){
    return sku;
}

Integer getQty(){
    return qty;
}

void setSku(String _sku){
    sku = _sku;
}

void setQty(Integer _qty){
    qty = _qty;
}
void incrementQty(){
    qty += 1;
}
}

The functions that serialize and deserialize the PullSheet object: 序列化和反序列化PullSheet对象的函数:

public static boolean saveSheet(Context context, PullSheet sheet){
    String fileName = "saved.szs";
    try {
        FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        Log.d("rep", fileName);
        oos.writeObject(sheet);
        oos.close();
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }

    return true;
}

public static PullSheet loadSheet(Context context, String fileName) {
    try {
        FileInputStream fis = context.openFileInput(fileName);
        ObjectInputStream is = new ObjectInputStream(fis);
        Object readObject = is.readObject();
        is.close();

        if(readObject != null && readObject instanceof PullSheet) {
            return (PullSheet) readObject;
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

    return null;
}

What I Need 我需要的

Please let me know where I'm going wrong. 请让我知道我要去哪里了。 I assume it's not the types that are causing the exception because all the classes implement Serializable, but I could be off. 我认为不是引起异常的类型,因为所有类都实现了Serializable,但是我可以关闭了。 Thanks in advance for any help 预先感谢您的任何帮助

While the class may implement Serializable, that means every field[1] inside it has to be either: 尽管该类可以实现Serializable,但是这意味着其内部的每个field [1]都必须是:

  • Serializable or 可序列化或
  • Transient 短暂的

Meaning for an instance UUID (a field in your class). 实例UUID(类中的字段)的含义。 Is that serializable? 那是可序列化的吗? Every field you have in your class has to implement Serializable as well. 您班级中的每个字段也必须实现Serializable。 If they don't implement serializable, they have to be transient . 如果它们不实现可序列化,则必须是transient If it is a static or final field, it doesn't have to be. 如果是静态字段或最终字段,则不必是。 Static and final fields aren't serialized anyways. 无论如何,静态字段和最终字段都不会序列化。

[1] : Every field means every field that is serializable. [1]:每个字段表示可序列化的每个字段。 This excludes final and static fields, or fields that are marked transient 这不包括最终字段和静态字段,或标记为瞬态的字段


Working example: 工作示例:

(All fields mentioned are of importance, and are not static, final or transient for the purpose of this example) (在此示例中,提到的所有字段都很重要,并且不是静态的,最终的或瞬态的)

  • Class1 implements Serializable. Class1实现Serializable。 Has fields of type Class2, Class3, int, double and ArrayList 具有类型为Class2,Class3,int,double和ArrayList的字段
  • Class2 implements Serializable has fields of type COntext Class2实现Serializable具有COntext类型的字段
  • Class3 implements serializable has fields of type int, double, Class2 Class3实现可序列化的类型为int,double,Class2的字段

Serializing Class1 would lead to an exception. 序列化Class1将导致异常。 Let us break this down quickly: 让我们快速分解一下:

  • Class2 is serializable Class2是可序列化的
  • Class3 is serializable Class3可序列化
  • int is serializable int可序列化
  • double is serializable double可序列化
  • ArrayList (can) be serializable if the class it holds is serializable 如果ArrayList持有的类是可序列化的,则它可以是可序列化的
  • Context is not serializable 上下文不可序列化

Because Class2 has a Context field (not serializable) and is serialized along with Class1 (because Class1 has a field of type Class2) you end up with an exception 因为Class2具有Context字段(不可序列化)并且与Class1一起序列化(因为Class1具有类型Class2的字段),所以您最终会遇到异常

It didn't implement Serializable when you serialized it. Serializable时,它没有实现Serializable You got an exception at that time. 那时您例外。 You fixed it to implement Serializable . 您已修复它以实现Serializable Then you tried to deserialize the old stream. 然后,您尝试反序列化旧流。 It doesn't work. 没用

EDIT 编辑

After adding an empty constructor to the problem class I am now getting an "incompatible" exception. 在将一个空的构造函数添加到问题类之后,我现在得到一个“不兼容”异常。

Because you changed the implicit serialVersionUID . 因为您更改了隐式serialVersionUID You don't need an empty constructor in a Serializable class. 您在Serializable类中不需要空的构造函数。

EDIT 2 编辑2

Some folk here appear to be unaware that when you attempt to serialize a non-serializable object, a NotSerializableException is (1) thrown and (2) written into the data stream in such a way that when you reach it when reading with readObject() , it is thrown again, exactly as shown in the OP's stack trace. 这里的一些人似乎没有意识到,当您尝试序列化不可序列化的对象时, NotSerializableException方式抛出NotSerializableException (1)并将(2)写入数据流,即使用readObject()读取时到达该数据流,再次将其抛出,完全与OP的堆栈跟踪中所示的一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM