我有这段代码:
public class Parent
{
int num;
Parent p;
Parent()
{
}
Parent(Parent s)
{
p=s;
}
void Print()
{
System.out.println(p.num);
}
}
和
public class Child
{
public static void main(String args[])
{
Parent p1=new Parent();
Parent p2=new Parent(p1);
Parent p3=new Parent(p2);
p2.num=5;//line 1
p2.Print();//Line 2
}
}
O / p为0.当我分别用p3.num=5
和p3.Print()
替换第1行和第2行时,这是真的。但是当我用p1.num=5
和p1.Print()
替换它时,我得到一个运行时错误(NullPointerException)。任何人都可以解释这种行为吗?
答案 0 :(得分:2)
p1
使用无参数构造函数进行实例化,该构造函数不初始化p
成员。因此,当您尝试访问Print
成员以获取空引用时,NullPointerException
会在num
上调用p.num
。
BTW,Child
类在这个例子中完全没用。它不会扩展Parent
类,并且您无论如何都不会实例化它。如果将main
方法移动到Parent
类,则相同的代码将表现相同。
答案 1 :(得分:1)
这是一个非常奇怪的类。实例的Print
方法打印与传递给构造函数的num
关联的p
。你有两个构造函数,其中一个没有设置p
,这意味着如果你使用那个构造函数,p
将是null
;您的其他构造函数会通过将其分配给Parent
来记住您提供的p
。
所以:
调用p1.Print()
将失败,因为p1
的{{1}}为p
,因此尝试使用null
会抛出NPE。
致电p.num
会显示 p2.Print()
的p1
num
,因为您从未将其设置为任何内容数据成员的默认值是“全零”值,因此0
为0
。
致电int
会显示 p3.Print()
的p2
,其中(原始代码中)将为num
,因为这就是你在调用5
之前设置的内容。
我说这是一个非常奇怪的类的原因是实例有一个p3.Print()
数据成员,但num
不打印他们的 Print
,它打印传入num
的{{1}}(如果有的话)。