NullPointerException in Java when using an object

2019-08-10 23:45发布

问题:

I'm pretty new to Java, as my post might give away.

I need to create a class (let's call it class A) which uses another class (class B) as one of its fields. Class A's constructor calls class B's constructor. So far things work fine. But when one of A's methods tries to use one of B's methods on the object of class B, I get a NullPointerException. This is probably too confusing so I wrote this simple example which creates the Exception.

This is class B:

 public class class_B {
    private int y;

    public class_B(int N) {      
        int y = N*N;
    }

    public int class_B_method() {
        return y;
    }
}

and this is class A:

public class class_A {
    private class_B obj;

    public class_A(int N) {           
        class_B obj = new class_B(N);
    }

    public int call_class_B_method() {
        return obj.class_B_method();
    }

    public static void main(String[] args) {

        int N =4;     
        class_A p = new class_A(N);
        int a = p.call_class_B_method();
    }

}

When I run class_A I get the exception on the line "int a = p.call_class_B_method();". I don't understand this, since 'obj' should have been created by the constructor 'class_B' and should be available for the method 'call_class_B_method'.

thanks!

回答1:

In the constructor of class_A you're not referencing the field obj, you're creating a new (local) variable with the same name. This is why the member never gets instantiated. You should write obj = new class_B(N) in the contructor.

There are several possible ways to mitigate such kind of errors:

  • Declare the field obj final, then the compiler will comlain if you don't instantiate it in the constructor. This of course only works when you don't want to change the field value later.
  • Always use this as identifier: this.obj = new class_B(N). This may clutter the code sometimes, so I guess this is a matter of taste.

Btw. by convention, Java class names always start with a capital letter. But this might be the case only for your example.



回答2:

This line in the constructor of class_A

class_B obj = new class_B(N);

initializes a local variable obj, not the obj field. This local object class_B gets created, and then almost immediately discarded. Usually compilers warn you of situations like this, for two reasons - first, you have a local variable that "shadows" a field, and second, a local variable is assigned and then never used again.

Change your code to

obj = new class_B(N);

to fix the problem.



回答3:

This line is wrong(because you lose the reference of the obj):

class_B obj = new class_B(N);

You should write:

obj = new class_B(N);