我很困惑为什么这个数组(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?
答案 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)
我花了很多时间自己搞清楚,
首先,您在代码中已经犯了一些基本错误
您不应该从构造函数中调用可覆盖的方法。在这里,您调用roll()
函数,该函数在子类中被覆盖。
public Die()
{
this.roll(); // shouldn't be done.
}
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不是特定于对象的数据,则将其设为静态。