为什么这个数组在初始化时是null?

时间:2016-11-29 18:08:00

标签: java arrays

我很困惑为什么这个数组(cumulativeWeights)被认为是null。这是我的(简化)代码:

public class WeightedDieTester
{
    public static void main(String[] args)
    {
        WeightedDie d = new WeightedDie();
    }
}
public class Die
{
    public Die()
    {
        this.roll();
    }
}
public class WeightedDie extends Die {
    double[] cumulativeWeights = {.1, .2, .3, .4, .5, 1};

    public WeightedDie() {
    }
    public int roll() {

        for (int i = 0; i < cumulativeWeights.length; i++) { //this is where the nullpointerException is occuring
            if (randNum < cumulativeWeights[i]) {
                return i + 1;
            }
        }
        return 6;
    }
}

所以是的,cumulativeWeights已初始化,不应为null。有谁知道我为什么会得到nullpointerexception?

4 个答案:

答案 0 :(得分:3)

Java按此顺序执行

Parent static block
Child static block
Parent initialization  block
Parent Constructor
Child initialization block
Child Constructor

因此,当您从Die调用roll时,数组尚未初始化。

答案 1 :(得分:2)

在超类的构造函数内部,类的字段未初始化。你应该从这一点开始调用roll。从最远的超类到实例的类初始化实例(并调用构造函数)。

答案 2 :(得分:2)

我花了很多时间自己搞清楚,

首先,您在代码中已经犯了一些基本错误

  1. 您不应该从构造函数中调用可覆盖的方法。在这里,您调用roll()函数,该函数在子类中被覆盖。

    public Die()
    {
        this.roll(); // shouldn't be done.
    }
    
  2. 2.您没有收到编译时错误,因为您已在子类中声明了变量cumulativeWeights。由于WeightedDie的对象尚未完成,因此尚未初始化这些变量的值。

    3.由于值未初始化为cumulativeWeights,因此您将获得空指针异常。 (但它已经声明,所以编译器让你编译没有错误)

    4.查看以下格式化代码的输出。下次从构造函数中调用可覆盖的方法时要小心

    /* package whatever; // don't place package name! */
    
    import java.util.*;
    import java.lang.*;
    import java.io.*;
    class Die
    {
        public double[] cumulativeWeights = {.1, .2, .3, .4, .5, 1};
        public Die()
        {
            System.out.println("constructing die");
            this.roll();
        }
        public int roll(){
            return 1;
        }
    }
    class WeightedDie extends Die {
         int randNum = 33; // value 0 is used because randNum isn't even initialized
        // even in your code!! cumulativeWeights is just declared, so no compile time error, you are using it even before the constructor of the child class is called!!!!
        public WeightedDie() {
            System.out.println("constructing weighteddie");
        }
        @Override
        public int roll() {
            System.out.println("using weighteddie and randNum = "+randNum);
            for (int i = 0; i < cumulativeWeights.length; i++) { //this is where the nullpointerException is occuring
                if (randNum < cumulativeWeights[i]) {
                    return i + 1;
                }
            }
            return 6;
        }
    }
    /* Name of the class has to be "Main" only if the class is public. */
    class Ideone
    {
        public static void main(String[] args)
        {
            WeightedDie d = new WeightedDie();
        }
    }
    

    输出:

    constructing die
    using weighteddie and randNum = 0
    constructing weighteddie
    

    我希望你明白我的观点。干杯!

答案 3 :(得分:0)

如果cumulativeWeights不是特定于对象的数据,则将其设为静态。