[英]NotSerializableException when classes implement Serializable
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)
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。
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;
}
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]都必须是:
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) (在此示例中,提到的所有字段都很重要,并且不是静态的,最终的或瞬态的)
Serializing Class1 would lead to an exception. 序列化Class1将导致异常。 Let us break this down quickly:
让我们快速分解一下:
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.