如何在Java中使用对象创建流程?

时间:2016-05-18 16:05:02

标签: java oop constructor

这里一般是Java和OOP的新手。

我试图理解何时可以使用某个对象的成员。具体来说,为什么我不能在类中调用它时将实例变量传递给构造函数?示例代码如下:

public class Point {

    public String name;

    {
        name = "Henry";
    }

    public Point()
    {
        this(this.name); // cannot reference this before supertype constructor has been called
    }

    public Point(String name)
    {
        this.name = name;
    }

}
之前曾经问过这样的事情,但我不知道如何向谷歌询问我在这里解释的内容。我知道我无法在this.name调用中引用this(this.name),因为尚未创建对象引用,但Java究竟是如何调用构造函数的?

构造函数将被执行的唯一时间是使用new Point()创建对象时,此时对象引用可用,并且编译器不会“有什么可抱怨的。如果可以将this.name分配给变量,然后将其传递给this(variable),它会起作用吗?有什么巨大的区别?我在这里完全误解了一些东西。

这就是我对其进行可视化的方式,这显然是不正确的:

Point myPoint = new Point();

myPoint.name现在等于"Henry"

Point()构造函数中,执行this(this.name) // which should be "Henry"

3 个答案:

答案 0 :(得分:2)

我不知道这是否完全回答了你的问题,因为它有点令人困惑,但我会尽我所能:

要创建新对象,请使用new操作数,例如Point point = new Point();。 您的对象可以/应该包含属性,并在创建public String name;时正确启动它(尽管您应该搜索它,因为它们不应该是公共的)。如果必须为属性分配默认值,则必须在声明后立即执行(例如public String name = "Henry";。再次,您可能想要搜索java常量来解决此问题。

此代码可以帮助您了解(我认为)您想要做的事情:

public class Point {

    public String name = "Henry";

    public Point() {

    }

    public Point(String name) {
        this.name = name; //changes current value (Henry) to the one sent as an argument.
    }


    public static void main(String[] args) {
        Point pointA = new Point();
        Point pointB = new Point("Other name");

        System.out.println(pointA.name);
        System.out.println(pointB.name);
    }
}

在此代码中,您可以找到空对象(new Point();)的实例化以及名称为“其他名称”(new Point("Other name");)的实例。

如果你运行它,你可以看到两个实例之间的差异。

希望这能帮到你!

修改 附:您可能还想搜索getter / setter。

答案 1 :(得分:1)

  

构造函数执行的唯一时间是使用新的Point(),创建对象时,对象引用可用,编译器没有任何东西抱怨。

我要说的是,关键点是对象引用仅在调用构造函数后才可用。因此,在构造函数的操作期间引用此并没有多大意义。

还要记住,通过继承,您可以在实例化/创建特定对象之前调用多个构造函数。例如:

[{
    "uid": null,
    "index": 0,
    "selected": null,
    "expanded": null,
    "id": "RA_PLTFRM_NOTIF",
    "text": "Platform Maintenance Notification",
    "parentId": null,
    "items": null
}, {
    "uid": null,
    "index": 0,
    "selected": null,
    "expanded": null,
    "id": "RA_ATTST_LANGUAGE",
    "text": "Attestation Language",
    "parentId": null,
    "items": null
}]

在这种情况下,你将有两个在Point完全实例化之前调用的构造函数(所以你在OP中提到的流程并不总是那么简单。)

Xavier Silva的答案代码很好,而且有吸气剂和镶嵌器也是理想的:

public class ParentPoint {
    public String name = "Parent Point";

    public ParentPoint() {
        // do something
    }
}

public class Point extends ParentPoint {

    public Point() {
        super();
        // do something else
    }

}

最后一位演示了getter和setter,其余代码未经修改。

答案 2 :(得分:0)

你可以通过清空this(this.name)构造函数来实现你的目标 - 这样,调用一个空构造函数 - 新的Point() - 将名称保留为Henry,并使用其他构造函数 - 例如new Point(“Bob”) - 将该名称(“Bob”)设置为名称。

我相信你也可以通过将“this”替换为“super”来实现。