Why does Java throw NullPointerException here?

2020-01-27 08:06发布

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 */

}

Hello guys. I'm learning Java through reading Robert Sedgwick's book on algorithms and I'm using his libraries such as StdOut, for example. But the question is about Java in general. I don't understand why Java here throws a NullPointerException. I do know what that means in general, but I don't know why it is here because here's what I think I'm doing:

  1. read an integer number from the file - the size of the array in the class Test. In my test example size=10, so no out-of-bound type of thing happens.

  2. print it.

  3. create the object N of type Test. In this object I think I create an array of size that I have just read from the file. For fun I initialize it from 0 to size-1 and print it. So far so good.

  4. and here where it all begins. Since my class is public and I've run the constructor I think I have the object N which as an attribute has the array x with size elements. However, when I'm trying to address x, for example,

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

    Java throws NullPointerException.

Why so? Please help and thank you very much for your time.

5条回答
放荡不羁爱自由
2楼-- · 2020-01-27 08:38
 int size=reader.readInt();  // size < 3
 StdOut.println(N.x[3]); // length of x[] less than 3, so x[3] case NullPointException
查看更多
趁早两清
3楼-- · 2020-01-27 08:45

what you did is called shadowing you shadowed your field x with local variable x. so all you need to do is avoiding this:

int[] x = new int [N]; is wrong, if you want your field to initialize instead of a local variable then you could do something like : x = new int [N]; for more information read this

查看更多
SAY GOODBYE
4楼-- · 2020-01-27 08:59

Inside public Test(int n):

Change

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

to

x = new int [N]; // Assigning it to x
查看更多
Luminary・发光体
5楼-- · 2020-01-27 09:00

change the first line in constructor from

int[] x = new int [N];

to

x = new int [N];

it should work...

Actually in constructor when you say int[] x, it is creating one more local variable instead setting data to public variable x... if you remove int[] from first line of constructor then it initizes the public variable & you will be able to print them in main() method

查看更多
Summer. ? 凉城
6楼-- · 2020-01-27 09:01

Everyone has given the code that would work. But the reason is something called as variable scoping. When you create a variable (by saying int[] x, you are declaring x as an integer array and by saying x = new int[4] you are assigning a new array to x). If you use the same variable name x everywhere and keep assigning things to it, it'll be the same across your class.

But, if you declare int[] x one more time - then you are creating one more variable with the name x - now this can result in duplicate variable error or if you're declaring in a narrower 'scope', you will be overriding your previous declaration of x.

Please read about java variable scopes to understand how scoping works.

查看更多
登录 后发表回答