为啥 Java 会在这里抛出 NullPointerException?

Posted

技术标签:

【中文标题】为啥 Java 会在这里抛出 NullPointerException?【英文标题】:Why does Java throw NullPointerException here?为什么 Java 会在这里抛出 NullPointerException? 【发布时间】:2015-06-01 07:21:18 【问题描述】:
public class Test 

    public int [] x;

    public Test(int N)
    
       int[] x = new int [N];
       for (int i=0;i<x.length;i++)
       
           x[i]=i;
           StdOut.println(x[i]);
       
    


    public static void main(String[] args)  

        String path = "/Users/alekscooper/Desktop/test.txt";
        In reader = new In(path);
        int size=reader.readInt();
        StdOut.println("Size = "+size);

        Test N = new Test(size);
        StdOut.println(N.x[3]);

    

    /* ADD YOUR CODE HERE */


大家好。我通过阅读 Robert Sedgwick 的算法书来学习 Java,并且我正在使用他的库,例如 StdOut。但问题一般是关于 Java 的。我不明白为什么这里的 Java 会抛出 NullPointerException。我确实知道这通常意味着什么,但我不知道为什么会在这里,因为这就是我认为我正在做的事情:

    从文件中读取一个整数——数组的大小 在类测试中。在我的测试示例中 size=10,所以不会发生超出范围的事情。

    打印出来。

    创建 Test 类型的对象 N。 在这个对象中,我想我创建了一个我刚刚拥有的大小数组 从文件中读取。为了好玩,我将它从 0 初始化为 size-1 和 打印它。到目前为止一切顺利。

    一切从这里开始。因为我的课是公开的,所以我跑了 构造函数我认为我有对象 N 作为属性 具有带有 size 个元素的数组 x。 但是,当我尝试 例如,寻址 x,

    StdOut.println(N.x[3]);

    Java 抛出 NullPointerException。

为什么会这样?请提供帮助,非常感谢您抽出宝贵时间。

【问题讨论】:

test.txt 中的内容是什么? 请发布异常的堆栈跟踪。 你可以参考这个SO问题***.com/questions/20671008/… 是的,您使用了一个局部变量而不是将该值分配给该字段。 【参考方案1】:

您所做的称为 shadowing,您使用局部变量 x 遮蔽了您的字段 x。所以你需要做的就是避免这种情况:

int[] x = new int [N]; 是错误的,如果您希望字段初始化而不是局部变量,那么您可以执行以下操作:x = new int [N]; 了解更多信息,请阅读 this

【讨论】:

哦,是的,我明白了。我理解这个概念,我认为这只是因为我在 Java 方面的经验非常有限,并且某些语法仍然看起来很奇怪。 @alekscooper1 很高兴您的问题解决了,如果有帮助请不要忘记标记为答案:) 我没有足够的声望来投票给答案,如果这就是你的意思。我当然会,如果可以的话。【参考方案2】:

改变构造函数的第一行

int[] x = new int [N];

x = new int [N];

它应该可以工作......

实际上,当您说 int[] x 时,在构造函数中,它正在创建另一个局部变量,而不是将数据设置为公共变量 x...如果您从构造函数的第一行删除 int[],那么它会初始化公共变量 &将能够在 main() 方法中打印它们

【讨论】:

【参考方案3】:

内部public Test(int n)

改变

int[] x = new int [N]; // Creating a local int array x

x = new int [N]; // Assigning it to x

【讨论】:

【参考方案4】:

每个人都给出了可行的代码。但原因是所谓的变量范围。当您创建一个变量时(通过说 int[] x,您将 x 声明为一个整数数组,并且通过说 x = new int[4] 您将一个新数组分配给 x)。如果您在任何地方都使用相同的变量名称 x 并​​继续为其分配东西,那么在您的班级中它将是相同的。

但是,如果您再声明一次 int[] x - 那么您将创建一个名为 x 的变量 - 现在这可能导致重复变量错误,或者如果您在更窄的“范围”中声明,您将覆盖您之前的 x 声明。

请阅读 java 变量作用域以了解作用域的工作原理。

【讨论】:

【参考方案5】:
 int size=reader.readInt();  // size < 3
 StdOut.println(N.x[3]); // length of x[] less than 3, so x[3] case NullPointException

【讨论】:

你是怎么知道大小会小于 3 的? 如 OP 所述,“在我的测试示例中 size=10,因此不会发生超出范围的事情”。

以上是关于为啥 Java 会在这里抛出 NullPointerException?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Python 会在 Pygame 中为“事件”变量抛出未绑定的本地错误? [关闭]

为啥 requests-mock 装饰器模式会在 pytest 中抛出“fixture 'm' not found”错误?

为啥我不断收到此空指针未知来源错误?

为啥 Oracle 不在这里抛出“不明确的列引用”?

FileNotFoundException 有时会被抛出,我不知道为啥

当 np.where 抛出 TypeError 时,为啥 np.vectorize 在这里工作?