Java返回可變引用對象問題整理
1.問題
/**
* 輸出: Mon Apr 26 10:54:10 CST 2010
* Mon Apr 26 10:54:10 CST 2010
*/
public static void main(String[] args){
Example test = new Example(new Date());
Date d = test.getDate();
double tenYearsInMillisSeconds = 10 * 365.25 * 24 * 3600 * 1000;
d.setTime((long) (d.getTime() - tenYearsInMillisSeconds));
System.out.println(d);
System.out.println(test.getDate());
}
public class Example {
private Date date;
public Example(Date date){
this.date = date;
}
public Date getDate() {
return date;
}
}
Date類破壞了Example的封裝,導(dǎo)致修改實例 d時影響了 test 的值,原因是Date類生成的對象是可變的。
2.對象與對象變量
Date birthday = new Date(); Date deadline = birthday;
這兩個變量引用同一個對象(請參見圖 4-4 )。

但一個對象變量并沒有實際包含一個對象,而僅僅引用一個對象。
在 Java 中,任何對象變量的值都是對存儲在另外一個地方的一個對象的引用。new 操作符的返回值也是一個引用。
Date birthday = new Date();可以理解為new Date() 構(gòu)造了一個 Date 類型的對象, 并且它的值是對新創(chuàng)建對象的引用。這個引用存儲在變量 birthday中。
Java 對象變量與 C++ 的引用并不同
可以將 Java 的對象變量看作 C++ 的對象指針。例如,
Date birthday; // Java
實際上,等同于
Date* birthday; // C++
所有的 Java 對象都存儲在堆中。 當(dāng)一個對象包含另一個對象變量時, 這個變量依然
包含著指向另一個堆對象的指針。
3.更改器方法與訪問器方法
上文還是沒有解釋清楚為什么Date類的對象是可變對象,原因在這。
假設(shè)在上文中Example類中使用Java中與Date類相近的LocalDate類便不會出現(xiàn)上述情況,測試可以自己去嘗試。
原因在于假設(shè)使用LocalDate類中的plusDays 方法來修改對象變量,它會生成一個新的LocalDate對象,然后把這個新對象賦值給調(diào)用者,原來的對象不做任何改動。
此類只訪問對象而不修改對象的方法有時稱為訪問器方法(accessor method)
而像Date類中的setTime方法會使得原對象的狀態(tài)發(fā)生改變,此類稱為更改器方法(mutator method)
4.解決方法
如果需要返回一個可變數(shù)據(jù)域的拷貝,就應(yīng)該使用 clone。這樣會創(chuàng)建一個當(dāng)前對象的副本,而不會對當(dāng)前對象造成影響。
public class Example {
private Date date;
public Example(Date date){
this.date = date;
}
public Date getDate() {
return (Date) date.clone();
}
}
5.不可變類
5.1什么是不可變類
不可變類指當(dāng)類被實例化后,該類的成員變量均不可被改變。
如JDK內(nèi)部自帶的很多不可變類Interger、Long、 Boolean和String等。
5.2優(yōu)缺點 優(yōu)點:
1.線程安全
2.易于構(gòu)造、使用和測試
3.可以被自由地共享缺點:對于每一個不同的值都需要對應(yīng)一個單獨的對象 5.3如何實現(xiàn)不可變類 Class需要用final修飾,保證類不能被繼承所有成員變量需要private修飾,保證成員變量不能直接被訪問類中不允許提供setter方法,保證成員變量不會被改變在getter方法中不能返回對象本身,返回對象的拷貝
到此這篇關(guān)于Java返回可變引用對象問題整理的文章就介紹到這了,更多相關(guān)Java返回可變引用對象問題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
用SpringBoot+Vue+uniapp小程序?qū)崿F(xiàn)在線房屋裝修管理系統(tǒng)
這篇文章主要介紹了用SpringBoot+Vue+uniapp實現(xiàn)在線房屋裝修管理系統(tǒng),針對裝修樣板信息管理混亂,出錯率高,信息安全性差,勞動強度大,費時費力等問題開發(fā)了這套系統(tǒng),需要的朋友可以參考下2023-03-03
Spring使用@Filter注解創(chuàng)建自定義過濾器
Spring 中鮮為人知但非常有用的注解之一是 @Filter,它支持自定義過濾器,下面我們就來深入研究一下如何使用 Spring 的 @Filter 注解來創(chuàng)建自定義過濾器吧2023-11-11
使用Java和PostgreSQL存儲向量數(shù)據(jù)的實現(xiàn)指南
在當(dāng)今的數(shù)字化時代,數(shù)據(jù)存儲的方式和技術(shù)正變得越來越復(fù)雜和多樣化,隨著機器學(xué)習(xí)和數(shù)據(jù)科學(xué)的發(fā)展,向量數(shù)據(jù)的存儲和管理變得尤為重要,本文將詳細(xì)介紹如何使用 Java 和 PostgreSQL 數(shù)據(jù)庫來存儲向量數(shù)據(jù),需要的朋友可以參考下2024-09-09
javax.management.InvalidApplicationException的問題解決
javax.management.InvalidApplicationException是與Java Management Extensions (JMX) API相關(guān)的一個常見異常,本文主要介紹了javax.management.InvalidApplicationException的問題解決,感興趣的可以了解一下2024-08-08

