Java 没有字段的抽象类上的NotSerializableException
这是我的小班级:Java 没有字段的抽象类上的NotSerializableException,java,serialization,Java,Serialization,这是我的小班级: import java.io.Serializable; public abstract class SerializableCallback extends Callback implements Serializable { private static final long serialVersionUID = 4544768712188843966L; public abstract void handleMessage(Message msg); }
import java.io.Serializable;
public abstract class SerializableCallback extends Callback
implements Serializable {
private static final long serialVersionUID = 4544768712188843966L;
public abstract void handleMessage(Message msg);
}
下面是它的更小的父级回调:
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() {}
测试在注释指示的行上给了我一个notserializableeexception
。这里有几件事是绝对不会引起这种情况的:
那么是什么导致了异常呢?您的类没有无参数构造函数。它有一个构造函数,它接受一个参数,即外部类的
this
。如果您使用testSerialization()static
,则可能会解决此问题
但是我怀疑您的直接真正问题是,您的嵌套类引用了外部类,并且外部类不可序列化。检查这些情况
在这些情况下,序列化失败:
- 删除实例变量
- 更改实例变量的类型
- 将实例变量从非瞬态更改为瞬态
- 将实例变量从非静态更改为静态
- 在层次结构中上下移动类
SerializableCallback
类在技术上是一个内部类
- 在非静态方法中声明时,匿名类本质上是非静态内部类
- 在静态方法中声明时,匿名类本质上是静态内部类
静态
有效的原因。由于它使您创建的匿名类成为静态类,因此它不再包含对测试类的隐式引用,因此它是可序列化的
请记住,在非静态级别声明的匿名类和内部类始终包含对封闭类的引用。如果没有,您就无法在匿名类中调用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
可能无法序列化。Kumar,您应该知道不要用代码格式突出显示“Removing”之类的随机词:“Removing”不是代码。这三个类没有嵌套,因此没有“outer”类。请解释一下为什么会有你提到的构造函数?无论如何,使testSerialization()
static
解决了这个问题。当您的方法不是static
时,您的嵌套类将成为一个内部类,它隐式地引用了OuterClass。无论您是否需要它,这个
作为字段。它通常被称为此$0
。要将此值(以及您可能使用的任何其他final
局部变量)传递给构造函数,“默认”构造函数必须采用附加参数。顺便说一句:如果创建名为this$0
的字段,它将创建名为this$0$
或this$0$
等的字段;)谢谢你的耐心和彻底!