父构造函数将父对象作为参数

时间:2014-11-11 10:08:31

标签: java class object

我有这段代码:

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=5p3.Print()替换第1行和第2行时,这是真的。但是当我用p1.num=5p1.Print()替换它时,我得到一个运行时错误(NullPointerException)。任何人都可以解释这种行为吗?

2 个答案:

答案 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,因为您从未将其设置为任何内容数据成员的默认值是“全零”值,因此00

  • 致电int会显示 p3.Print() p2,其中(原始代码中)将为num,因为这就是你在调用5之前设置的内容。

我说这是一个非常奇怪的类的原因是实例有一个p3.Print()数据成员,但num不打印他们的 Print,它打印传入num的{​​{1}}(如果有的话)。