今天同事在群里突然发了一段Java代码,是关于连等赋值的,代码大致逻辑如下:
public class MainTest {
public MainTest note;
public int i;
public MainTest(int j){
this.i=j;
}
public void println(){
System.out.println(" "+i);
}
public static void main(String[] args) {
MainTest n1=new MainTest(1);
MainTest n2=new MainTest(2);
n1=n1.note=n2;//------1-------
//n1.note=n1=n2;//------2-------
n1.println();
n1.note.println();
}
}
看Log:
2
Exception in thread "main" java.lang.NullPointerException
at com.jason.thread.MainTest.main(MainTest.java:27)
这段代码很简单,但是可能有些人对于打印出的结果感觉不大理解,先说一下这段代码的打印结果,在上述代码1、2处任意注释掉一条代码,程序都会报NullPointerException,这里说一下我个人的理解,如果理解的不对欢迎大家指出来,帮我改正错误,同时也给大家一个正确的答案。
※ Java是自右向左逐一赋值的,比如:A=B=C=0,首先给C赋值0,即C=0,然后B=C;最后A=B。了解了Java的赋值顺序,那么我们来分析一下上边的代码,首先,创建了两个MainTest对象并赋值了内部int类型成员变量,此时,n1,n2内部成员变量note都未赋值,为空,然后看----1-----处代码的赋值过程。程序会先拿到n1,n1.next,n2对象,按照上文提到的赋值顺序,我们知道首先是n1.note=n2,执行完后n1.note的句柄由null指向了n2指向的内存地址;然后就是n1=n1.note;这里因为ni.note指向了堆内存中的n2指向的地址,所以n1也就指向了n2指向的内存地址。因为n2中的note对象为null,所以在这里调用n1.note.println()会报NullPointerException,这样第一种情况就分析完了;那么接下来看第二种情况,也就是n1.note=n1=n2;首先程序拿到n1.note、n1、n2的句柄,然后将n1指向n2指向的堆内存中对象值,这里n1的note为null,最后n1.note对象的句柄指向了n1,因为在程序开始时就拿到了n1.note,所以这里的n1.note是原n1中的对象,而此时的n1是指向n2的,它的note此时为null,所以如果你这是调用n1.note.println()也是会报NullPointerException的。这就是我的理解。如果不对,望大神及时指点,以免误导他人,同时大家也能对相关知识点更加清楚,谢谢!
※ A=B=C=0虽然赋值顺序是C=0;B=C;A=B的,但是在代码中A=B=C=0;与代码C=0;B=C;A=B;是不一样的。