这是我的小班:
import java.io.Serializable;
public abstract class SerializableCallback extends Callback
implements Serializable {
private static final long serialVersionUID = 4544768712188843966L;
public abstract void handleMessage(Message msg);
}
这是更加平坦的父Callback
:
public abstract class Callback {
public abstract void handleMessage(Message msg);
}
这是我的测试:
public void testSerialization() throws IOException, ClassNotFoundException {
SerializableCallback c = new SerializableCallback() {
private static final long serialVersionUID = -4852385037064234702L;
@Override
public void handleMessage(Message msg) {
callbackMethod();
}
};
FileOutputStream fos = new FileOutputStream(FILE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(c); // fails
out.close();
FileInputStream fis = new FileInputStream(FILE);
ObjectInputStream in = new ObjectInputStream(fis);
Object object = in.readObject();
@SuppressWarnings("unused")
SerializableCallback d = (SerializableCallback) object;
}
private void callbackMethod() {}
测试在评论指示的行上给了NotSerializableException
。这里有几件事情肯定会导致不:
那么 会导致异常?
答案 0 :(得分:6)
您的类没有no-arg构造函数。它有一个构造函数,它接受一个参数,即外部类的this
。如果您创建了testSerialization()static
,它可能会解决问题。
但我怀疑你的直接真正的问题是你的nest类有一个对外部类的引用而外部类不是Serializable。
答案 1 :(得分:1)
检查这些案例
在这些条件下,序列化失败:
删除实例变量。
更改实例变量的类型。
将实例变量从非瞬态更改为瞬态。
将实例变量从非静态更改为静态。
在层次结构中上下移动班级。
答案 2 :(得分:1)
为了进一步阐述您对Peter的答案的评论(评论时间太长),您的测试方法中的匿名SerializableCallback
类在技术上是一个内部类。
这就是切换到static
的原因。由于它创建了一个静态类的匿名类,因此它不再对您的测试类进行隐式引用,因此它是可序列化的。
请记住,在非静态级别声明的匿名和内部类始终包含对封闭类的引用。如果没有,你将无法在匿名类中调用callbackMethod()
,因为匿名类没有声明它。
当ObjectOutputStream
尝试序列化您的匿名SerializableCallback
时,它会尝试序列化回调和测试类,因为SerializableCallback
持有对它的引用。这就像试图序列化这个类:
// Declared in its own file
public class MySerializableCallback extends SerializableCallback {
private static final long serialVersionUID = -4852385037064234702L;
// Equiv to Callback.this in an inner class
private final CallbackTest test;
public MySerializableCallback(CallbackTest test) {
this.test = test;
}
@Override
public void handleMessage(Message msg) {
test.callbackMethod();
}
}
如果你试图序列化这个类,很明显它会失败,因为CallbackTest
可能不是可序列化的。