簡體   English   中英

Java中構造函數中的最終參數

[英]Final parameters in a constructor in Java

我正在學習Java中的類和構造函數。 我在一個示例程序中亂用代碼,似乎無法弄清楚到底發生了什么。

這段代碼不會編譯對我來說有意義:

class Line {
Point start;
Point end;

Line(final Point start, final Point end) {

    this.start = new Point(start);
    this.end = new Point(end);
    start = new Point(0.4, 0.4);

}...

我試圖通過調用Point對象的構造函數將原始的起始點對象引用分配給另一個Point對象。 final關鍵字與此沖突。

但是當我從Point start參數中刪除final關鍵字時......

class Line {
Point start;
Point end;

Line(Point start, final Point end) {

    this.start = new Point(start);
    this.end = new Point(end);
    start = new Point(0.4, 0.4);

}

它似乎沒有實際更改引用,傳遞給Line構造函數的Point對象仍然似乎指向原始對象,並且由Line構造函數的代碼保持不變。 什么給出了什么? 這是否與引用的'start'在Line構造函數的作用域中是本地的這一事實有關?

Java不使用pass-by-reference,它使用ALWAYS pass-by-value。 實際上,Java中的引用類型只是指針,並不像C#中的引用那樣共享相同的含義。

所以當你在構造函數中執行此語句時:

start = new Point(0.4, 0.4);

傳入參數的原始Point不會改變。 但是,局部變量(表示參數)將指向由坐標定義的新Point0,4, 0,4

為了更好地理解,請閱讀這篇文章: Java是Pass-by-Value,Dammit!

該變量是構造函數的本地變量。 因此,在構造函數之外為其分配新引用沒有意義,因為它不存在於構造函數之外。

實現這種效果的一種方法是將其包裝在另一個對象中。 並傳遞對可變包裝器的引用。

它似乎並沒有真正改變參考

您無法更改用於在該方法內調用方法的參數的引用。 參數的值(對象的引用)將復制到方法參數中,因此您可以對同一對象進行第二次引用。 在方法內部,您只能修改第二個引用,並且不能更改原始引用。 你唯一能做的就是修改引用的對象。

當您執行“start = new Point(0.4,0.4);”時,您將引用構造函數上收到的開頭。 由於構造函數將其定義為final,因此將非新值賦值給變量是非法的。

細節是,當java使用pass-by-value方法時,即使你不使用final並更改構造函數中的值,原始值的值(作為參數傳遞給方法的值)仍然是相同。

從“Line(Point start,final Point end){”初始化之后,通過執行“this.start = new Point(start)”來修改“start”時,你沒有替換堆上的實際對象是什么“開始”點但是在堆上的新Point對象與現有的單獨區域分配並修改現有指針“start”(STACK上的標量類型)以指向新分配。

構造函數是一種特殊用途的方法(函數),在java堆上進行對象分配后由java的new運算符調用。 因此,當調用方法時,會分配堆棧,並且在堆棧(不是堆)上分配方法中的任何標量類型(在java中它的原始類型,如int,double,char ...)和REFERENCE。 當您將狀態寫為“final Object o = new Object()”時,您已在內存中分配了兩個內容。
首先,java堆上的“new Object()”。 (堆)
第二,指向堆棧上方的指針,即“對象o”。 (堆)
在您的情況下,您只是嘗試覆蓋標量類型的“最終對象o”,並且僅在jvm內存(STACK)上讀取。

class Line {
Point start;
Point end;

// On the first line "Line(Point start, Point end) {",
// two references and two actual Objects that references point to
// are already allocated in memory.  
// So you've allocated four things.
Line(Point start, final Point end) { // "start" initialized on stack as final
    this.start = new Point(start); // tried to modify final variable on stack.
    this.end = new Point(end);
    start = new Point(0.4, 0.4);

}

暫無
暫無

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

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