轉自CSDN-詳述 Java 中的別名現象
在任何程式語言中,賦值操作都是最常見的操作之一,Java 自然也不例外。賦值時,使用賦值操作符=
,它的意思是:“將等號右邊的值(右值),複製給左邊的值(左值)”。右值可以是任何常數、變數或者表示式(只要它能生成一個值就行)。但左值必須是一個明確的、已命名的變數。也就是說,必須有一個物理空間可以儲存等號右邊的值。例如:
int a = 4;
就是將一個常數賦給一個變數。但是不能把任何東西賦給一個常數。
對於基本資料型別來說,賦值是很簡單的,因為基本資料型別(在堆疊中)儲存了實際的數值,而並非指向一個物件的引用,所有在為其賦值的時候,是直接將一個地方的內容複製到了另一個地方。但是在為物件“賦值”的時候,情況卻發生了變化。對一個物件進行操作的時候,我們真正操作的是物件的引用,所以倘若“將一個物件賦值給另一個物件”,實際上是將“引用”從一個地方複製到另一個地方。這意味著如果物件在賦值的時候用b =
,那麼物件b
和c
都指向原本只有c
指向的那個物件。通過下面的程式碼示例,我們將看到這個現象:
package com.hit.operator; /** * @Author Charies Gavin * @Date 2017/8/26,下午1:38 * @GitHub https://github.com/guobinhit */ public class Book { int price; }
如上面的程式碼所示,我們建立了一個Book
類,用來表示書籍,其僅有一個欄位price
,表示書籍的價格。
package com.hit.operator; /** * @Author Charies Gavin * @Date 2017/8/26,下午1:38 * @GitHubhttps://github.com/guobinhit */ public class Assignment { public static void main(String[] args) { // 建立兩個實體物件 Book thinkingInJava = new Book(); Book headFirstPattern = new Book(); // 分別賦值 thinkingInJava.price = 108; headFirstPattern.price = 68; System.out.println("Thinking In Java : price is " + thinkingInJava.price); System.out.println("Head First Pattern : price is " + headFirstPattern.price); // 將 headFirstPattern (的引用)賦值給 thinkingInJava thinkingInJava = headFirstPattern; System.out.println("Thinking In Java : price is " + thinkingInJava.price); System.out.println("Head First Pattern : price is " + headFirstPattern.price); // 修改 thinkingInJava 的價格(值),半價出售 thinkingInJava.price = 54; System.out.println("Thinking In Java : price is " + thinkingInJava.price); System.out.println("Head First Pattern : price is " + headFirstPattern.price); } }
如上面所示,我們建立了兩個書籍物件thinkingInJava
和headFirstPattern
,並分別對其價格進行賦值;然後,將物件headFirstPattern
的引用賦值給thinkingInJava
;接下來,呼叫thinkingInJava.price
,修改其價格為半價。最後,執行程式,輸出結果。顯然,由於物件的賦值是操作的物件引用,因此在我們改變thinkingInJava
的價格時,headFirstPattern
的價格也隨之改變。這種現象,我們稱之為“別名現象”。
當然,我們有時候並不希望發生別名現象,但如何避免呢?其實,想要避免別名現象也很簡單,以上面的程式碼為例,我們只需要將物件賦值時的語句略作修改即可,如下所示:
package com.hit.operator; /** * @Author Charies Gavin * @Date 2017/8/26,下午1:38 * @GitHub https://github.com/guobinhit */ public class Assignment2 { public static void main(String[] args) { // 建立兩個實體物件 Book thinkingInJava = new Book(); Book headFirstPattern = new Book(); // 分別賦值 thinkingInJava.price = 108; headFirstPattern.price = 68; System.out.println("Thinking In Java : price is " + thinkingInJava.price); System.out.println("Head First Pattern : price is " + headFirstPattern.price); // 將 headFirstPattern (的屬性值)賦值給 thinkingInJava thinkingInJava.price = headFirstPattern.price; System.out.println("Thinking In Java : price is " + thinkingInJava.price); System.out.println("Head First Pattern : price is " + headFirstPattern.price); // 修改 thinkingInJava 的價格(值),半價出售 thinkingInJava.price = 54; System.out.println("Thinking In Java : price is " + thinkingInJava.price); System.out.println("Head First Pattern : price is " + headFirstPattern.price); } }
如上面所示,當我們將thinkingInJava = headFirstPattern
修改為thinkingInJava.price = headFirstPattern.price
之後,別名現象即可消除。
溫馨提示:此內容源於《Java程式設計思想》,可以通過閱讀《Java程式設計思想》瞭解更多的內容。
原博地址:https://blog.csdn.net/qq_35246620/article/details/77601547