我有一个非常奇怪的问题。 (非常重要的说明:这是一个例子,因为我无法粘贴原始代码,我将其编写为没有编译器的文本。)我有2个类:
class B {
private int num = 9;
public int getNum(){
return num;
}
public void setNum(int num){
this.num = num;
}
}
class A {
private B b = new B();
public void setB(B b){
b.setNum(b != null? b.getNum() : 8);
}
public B getB(){
if (b == null)
System.out.println("How possible?");
return b;
}
}
现在,有时我会得到印刷品......但我不知道那是怎么回事。
A是一个序列化的类,但我无法弄明白。
答案 0 :(得分:5)
这是不可能的,不。当您尝试编译时,A.getB()
的定义会出现类型错误,而A.setB()
的定义看起来也很可疑(阴影b
)。
答案 1 :(得分:3)
在某些情况下b
可能为null:
b
可能会被反射设置为null,从而绕过你的二传手。b
可能会显式恢复为null。或者,如果B
不可序列化,则将其标记为瞬态以避免错误并且不会恢复。要验证简单的序列化工作流程,请使用以下代码:
Object object = "someString";
ByteArrayOutputStream holder = new ByteArrayOutputStream();
new ObjectOutputStream(holder).writeObject(object);
Object readObject = new ObjectInputStream(new ByteArrayInputStream(holder.toByteArray())).readObject();
System.out.println(readObject);
其中第一行被您要测试的实际对象替换
答案 2 :(得分:2)
如果您设法序列化具有A
的{{1}}实例,那么您将获得一个NPE。原因是在反序列化期间,未调用构造函数,因此b == null
未运行,因此private B b = new B();
保持b
。
答案 3 :(得分:1)
在将B的初始化添加到类之前,您是否序列化了A的实例?
如果是这种情况,您可以获得A的实例,其中b为null,因为未调用构造函数(初始化类的成员是隐式构造函数的一部分)。
然后你需要在类A中添加readObject()的实现,你可以检查b是否为null并在必要时初始化它。
答案 4 :(得分:0)
此行不会编译:
b.setNum(b != null? b.getNum : new B());
答案 5 :(得分:0)
那么,这个怎么样?如果您将B作为参数,为什么不使用它呢?
class A {
private B b = new B();
public void setB(B b){
if(b != null) {
this.b = b;
}
}
public B getB(){
return b;
}
}
答案 6 :(得分:0)
只是一个想法:替换
System.out.println("How possible?");
与
new Exception().printStackTrace();
这应该让您更容易看到之前发生的事情。否则,没有更多信息,唯一可能的原因是序列化。