簡體   English   中英

Java中的對象創建流程如何工作?

[英]How does the flow of object creation work in Java?

一般而言,這里是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;
    }

}

之前曾有人問過類似的問題,但是我不知道如何問Google我在這里解釋什么。 我知道我無法在this(this.name)調用中引用this.name ,因為尚未創建對象引用,但是Java究竟如何調用構造函數?

該構造函數將要執行的唯一時間是用在創建對象時, new Point()而此時一個對象的引用可用,而編譯器不會有什么可抱怨的。 如果可以將this.name分配給變量,然后將其傳遞給this(variable) ,那會可行嗎? 有什么大的不同? 我完全誤會了這里的東西。

這是我可視化的方式,這顯然是不正確的:

Point myPoint = new Point();

myPoint.name現在等於"Henry"

Point()構造函數中,執行this(this.name) // which should be "Henry"

我不知道這是否能完全回答您的問題,因為這有點令人困惑,但我會盡力而為:

為了創建一個新對象,您可以使用new操作數,例如Point point = new Point(); 您的對象可以/應該包含屬性,並且您在創建public String name;時就已經正確啟動了它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(); )和一個名稱為“ Other name”( new Point("Other name"); )的實例。

如果運行它,則可以看到兩個實例之間的差異。

希望這對您有所幫助!

編輯: PS您可能還想搜索有關吸氣劑/設置者。

構造函數唯一要執行的時間是使用new Point()創建對象時,此時可以使用對象引用 ,並且編譯器沒有什么可抱怨的。

我要說的關鍵是,對象引用僅調用構造函數之后才可用。 因此在構造函數的操作中引用它實際上沒有任何意義。

還請記住,通過繼承,可以在實例化/創建特定對象之前調用多個構造函數。 例如:

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

    public ParentPoint() {
        // do something
    }
}

public class Point extends ParentPoint {

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

}

在這種情況下,將有兩個構造函數在Point完全實例化之前被調用(因此,您在OP中提到的流程並不總是那么簡單)。

澤維爾·席爾瓦(Xavier Silva)的答案代碼是一個很好的答案,同時具有吸氣劑和吸氣劑也將是理想的選擇:

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 void setName(String newName) {
        this.name = newName;
    }

    public String getName() {
        return this.name;
    }


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

        System.out.println(pointA.name); // Henry
        System.out.println(pointB.name); // Other name

        pointA.setName("New name");
        System.out.println(pointA.getName()); // New name
    }
}

最后一點演示了getter和setter,其余代碼未修改。

您可以通過清空this(this.name)構造函數來實現目標-這樣,調用一個空的構造函數-new Point()-將名稱保留為Henry,然后使用其他構造函數-例如new Point(“ Bob”)-將該名稱(“鮑勃”)設置為名稱。

我相信您也可以通過將“ this”替換為“ super”來實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM