2016-11-29 43 views
1

我很困惑,为什么这个数组(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已经初始化,并不能为空。有谁知道为什么我得到这个nullpointerexception?

+4

因为在'cumulativeWeights'已经被分配之前你在'Die'构造函数中调用'roll()'。 –

+4

这甚至不应该编译。 – chrylis

+0

'死'是抽象类吗? –

回答

2

在超类的构造函数内部,类的字段不会被初始化。你不应该从这个角度打电话。实例从最远的超类到实例的类被初始化(并且调用构造函数)。

3

的Java执行顺序

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

因此,当您从模具叫卷,阵列尚未初始化。

0

如果累计权重不是对象特定的数据,则将其设为静态。

2

花了很多时间,我找出自己,

首先,有你在你的代码做了一些基本的错误

  1. 你不应该叫从重写的方法一个构造函数。在这里你调用roll()函数,该函数在子类中被覆盖。因为你已经宣布你的子类的变量cumulativeWeights

    public Die() 
    { 
        this.roll(); // shouldn't be done. 
    } 
    

2.You没有得到一个编译时错误。由于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 

我希望你有我的观点。干杯!

相关问题