我在一些静态类声明中遇到了一个奇怪的 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 声明(私有(private)静态类...)处抛出 NPE,我不知道为什么。
没有静态 block ,flag2 永远不会设置为空。
假设“静态类 MyStaticClass”在第 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 ),异常是相似的,但它是在属性声明行抛出的,而不是声明类的行。
最佳答案
当声明可能是基元的字段时,你应该问自己这个问题;这是否应该为 null
。如果该值可以为空,则可以使用包装器或毒丸值。但是,字段不应为 null
如果可以避免,则不应使用包装器。使用原语不仅会更快,而且会更清楚值不能为null
在回答您的问题时,您得到了一个 NPE,因为您的值为 null
使用 private static class
不会改变这一点。我建议您将代码断点并在调试器中查看它。
The stacktrace is saying that an NPE is throwing at line 400 MyClass$MyStaticClass.access$1300. What is that .access property?
使用私有(private)字段和类可能会造成混淆,因为 JVM 实际上并不像 Java 那样支持访问私有(private)成员。编译器生成允许此访问的代码,从而产生访问器方法。
从异常来看,最可能的解释是flag2为null
。
所以我建议
- 使用调试器查看发生了什么。
- 可以使用原语
- 如果在其他类中访问成员,则将您的访问包设为本地而不是私有(private)。
关于java - NPE 在静态类声明时被抛出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24504385/