我在一些静态课堂宣言中面对一个奇怪的NPE,我不知道为什么。
我有一个虚拟对象只是为了携带数据(是一个内部类),如下所示:
private static class MyStaticClass { //this is line 400
private String a;
private String b;
private String c;
private String d;
private Boolean flag1 = Boolean.FALSE;
private Boolean flag2 = Boolean.TRUE;
private Boolean flag3 = Boolean.TRUE;
private List<String> list = Collections.EMPTY_LIST;
public MyStaticClass() {}
public MyStaticClass(AnotherDataObject data) {
a = data.getA();
b = data.getB();
c = data.getC();
d = data.getD();
}
}
客户端代码(MyClass.myMethod)如下所示:
public class MyClass {
public void myMethod() {
Map<Key, MyStaticClass> thisMap = new HashMap<Key, MyStaticClass>(DEFAULT_BUFFSIZE);
//stuff
for() {
//stuff
MyStaticClass instance = new MyStaticClass(value1, value2, value3);
thisMap.put(generatedKey, instance);
}
//stuff
for() { //every key
MyStaticClass myStaticClassInstance = map.get(key); //this isn't null, i checked it.
if(randomObject.flag && myStaticClassInstance.flag2) {
//do stuff
}
}
//more stuff
}
private static class MyStaticClass {
//look the previous code snippet for more info
}
}
现在,我有一个运行线性(无并发)的函数,并在某些时候评估下一句话:
if(randomObject.flag && myStaticClassInstance.flag2) //randomObject is another class
当JVM评估这句话时,会在MyStaticClass声明(私有静态类......)中抛出一个NPE,我不知道为什么。
没有静态块,flag2永远不会设置为null。
让我们说&#34;静态类MyStaticClass&#34;在第400行声明。因此,堆栈跟踪就是这样:
java.lang.NullPointerException
at org.mypackage.MyClass$MyStaticClass.access$1300(MyClass.java:400)
at org.mypackage.MyClass.myMethod(MyClass.java:283)
at org.mypackage.AsyncDestination$1.run(AsyncDestination.java:102)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
编辑:我已经使用MyStaticClass添加了一个简单的测试作为null(https://gist.github.com/anonymous/35b94fea2a993fc350e4),异常类似,但它被抛出属性声明行,而不是声明类的行
答案 0 :(得分:1)
当声明可能是原始字段的字段时,你应该问自己这个问题;应该是null
还是null
。如果值可以为null,则可以使用包装器或毒丸值。但是,如果您可以避免使用包装器,那么该字段不应该是null
。使用原语不仅会更快,而且值也更加清晰null
在回答您的问题时,您获得的是NPE,因为您的值为private static class
使用null
不会更改此值。我建议您断开代码并在调试器中查看它。
堆栈跟踪说NPE正在400线MyClass $ MyStaticClass.access $ 1300投掷。什么是.access属性?
使用私有字段和类可能会让人感到困惑,因为JVM实际上并不像Java那样支持对私有成员的访问。编译器生成允许此访问的代码,从而产生访问器方法。
从例外情况来看,最可能的解释是flag2是{{1}}。
所以我建议