class A implements Serializable{
int a;
Thread th;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public Thread getTh() {
return th;
}
public void setTh(Thread th) {
this.th = th;
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
a.setA(10);
//a.setTh(new Thread());
try {
ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream(new File("G:\\Sample1.db")));
oos1.writeObject(a);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ObjectInputStream ois1 = new ObjectInputStream(new FileInputStream(new File("G:\\Sample1.db")));
A a1 = (A)ois1.readObject();
System.out.println(a1.getA()+" "+a.getTh());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
上面的代码将正常运行但是如果我取消注释a.setTh(new Thread());它抛出NotSerializableException。 由于Thread不是Serializable,为什么默认的序列化过程不会在它自身之前抱怨“th”变量。
答案 0 :(得分:3)
Thread
本身没有实现Serializable
,但这里是Thread
的子类,它执行:
class SerializableThread extends Thread implements Serializable {
@Override public void run() {}
}
SerializableThread
现在是Serializable
和Thread
,因此可以序列化它的实例。
编译器不知道您是否会在引用中存储不可序列化的Thread
或可序列化的Thread
(或null
,这也是可序列化的),因此它不会停止向实现Thread
的类添加Serializable
字段。
如果您想确保只设置可序列化的Thread
,则可以更改setter方法的类型,例如:
public void setTh(SerializableThread th) {
或
public <T extends Thread & Serializable> void setTh(T th) {
但是,值得注意的是,这并不能完全保证th
的可序列化,因为它可以传递地包含对非可序列化实例的引用。这只是Java序列化机制的局限之一。
答案 1 :(得分:2)
作为一个类的线程是不可序列化的,出于很多非常实际的原因,但理论上,可能会从Thread派生出一个可序列化的类。
我建议你制作一个transient
因为反序列化一个Thread实例没有意义。