调用Java关键字super

时间:2013-04-23 04:40:26

标签: java super

我最近在测试潜在工作时有以下代码。

class Point {
    protected final int x, y;
    private final String name;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
        name = makeName();
    }

    protected String makeName() {
        return "[" + x + "," + y + "]";
    }

    public final String toString() {
        return name;
    }
}

public class ColorPoint extends Point {
    private final String color;

    ColorPoint(int x, int y, String color) {
        super(x, y);
        this.color = color;
    }

    protected String makeName() {
        return super.makeName() + ": " + color;
    }

    public static void main(String[] args) {
        System.out.println(new ColorPoint(4, 2, "purple"));
    }
}

测试询问程序员打算打印出来的是什么,[4,2]:紫色。它还询问了实际打印出来的内容,即[4:2]:null。我想知道的是为什么。

3 个答案:

答案 0 :(得分:3)

在子类ColorPoint中,当调用超类Point的构造函数时,尚未分配变量color的值。因此,当调用makeName()方法时,color实际上是null,因此name变量变为[4,2]:null,这就是您在打印时看到的内容。

答案 1 :(得分:3)

观察创建新ColorPoint实例时会发生什么:

  • ColorPoint实例
  • 分配内存
  • xyname设置为默认值
  • ColorPoint构造函数被称为
  • ColorPoint构造函数调用Point构造函数
  • Point构造函数分配给xy
  • Point构造函数调用makeName方法。
  • this.makeName解析为ColorPoint.makeName
  • ColorPoint.makeName来电Point.makeName
  • Point.makeName观察xy已设置,并根据需要发挥作用
  • ColorPoint.makeName观察colornull,并采取相应行动
  • Point构造函数分配给name并返回
  • ColorPoint构造函数分配给color并返回。哎呀,太晚了。

final关键字确保将特定字段或变量分配给一次(编译器会这样做;它仍然可以通过反射进行更改)。编译器还确保在写入本地变量之前不会读取它。在读取类字段之前,没有这样的写入规定。

这就是为什么,如前所述,你永远不应该调用可以从构造函数中覆盖的方法。

答案 2 :(得分:2)

原因在代码中很明显。

ColorPoint类的构造函数调用makeName Point方法。此时private final variable color尚未初始化。