[英]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
不會改變。 但是,局部變量(表示參數)將指向由坐標定義的新Point
: 0,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.