NPE被抛出静态类声明

时间:2014-07-01 07:10:38

标签: java static nullpointerexception

我在一些静态课堂宣言中面对一个奇怪的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),异常类似,但它被抛出属性声明行,而不是声明类的行

1 个答案:

答案 0 :(得分:1)

当声明可能是原始字段的字段时,你应该问自己这个问题;应该是null还是null。如果值可以为null,则可以使用包装器或毒丸值。但是,如果您可以避免使用包装器,那么该字段不应该是null。使用原语不仅会更快,而且值也更加清晰null

在回答您的问题时,您获得的是NPE,因为您的值为private static class使用null不会更改此值。我建议您断开代码并在调试器中查看它。

  

堆栈跟踪说NPE正在400线MyClass $ MyStaticClass.access $ 1300投掷。什么是.access属性?

使用私有字段和类可能会让人感到困惑,因为JVM实际上并不像Java那样支持对私有成员的访问。编译器生成允许此访问的代码,从而产生访问器方法。

从例外情况来看,最可能的解释是flag2是{{1}}。

所以我建议

  • 使用调试器查看发生了什么。
  • 使用原语是可能的
  • 如果在其他类中访问成员,则使您的访问包本地而不是私有。