"注意不要編寫返回引用可變對(duì)象的訪問(wèn)器方法".因?yàn)闀?huì)破壞類的封裝性,引用的內(nèi)容可能會(huì)被改變,產(chǎn)生業(yè)務(wù)邏輯上的錯(cuò)誤.
什么是可變對(duì)象?
先要搞清楚java中值傳遞和引用傳遞的問(wèn)題,總結(jié)如下:
1.對(duì)象就是傳引用
2.原始類型就是傳值
3.String,Integer, Double等immutable類型因?yàn)闆]有提供自身修改的函數(shù),每次操作都是新生成一個(gè)對(duì)象,所以要特殊對(duì)待??梢哉J(rèn)為是傳值。
Integer 和 String 一樣。保存value的類變量是Final屬性,無(wú)法被修改,只能被重新賦值/生成新的對(duì)象。 當(dāng)Integer 做為方法參數(shù)傳遞進(jìn)方法內(nèi)時(shí),對(duì)其的賦值都會(huì)導(dǎo)致 原Integer 的引用被 指向了方法內(nèi)的棧地址,失去了對(duì)原類變量地址的指向。對(duì)賦值后的Integer對(duì)象做得任何操作,都不會(huì)影響原來(lái)對(duì)象。
所以,可變對(duì)象即immutable類型外的一般對(duì)象.[immutable類:如果類中的每個(gè)方法否不會(huì)改變其對(duì)象,這種類就是不可變的類.]
如果需要返回一個(gè)可變對(duì)象的引用,首先對(duì)它克隆,使用.clone
,如return hireDay.clone();
,會(huì)生成另一個(gè)內(nèi)存位置上的對(duì)象副本.
很多人對(duì)"java程序設(shè)計(jì)語(yǔ)言總是采用按值調(diào)用"這句話與引用傳遞產(chǎn)生誤會(huì),認(rèn)為矛盾,其實(shí)不矛盾,引用傳遞時(shí),方法調(diào)用的是對(duì)象的拷貝值,也是對(duì)類對(duì)象的引用,當(dāng)方法調(diào)用結(jié)束時(shí),拷貝值不再使用,方法執(zhí)行過(guò)程中通過(guò)拷貝值修改的對(duì)象值被改變.
package com.ghw.test;
import java.util.Date;
/**
* java core中提到不要編寫返回引用對(duì)象的訪問(wèn)器方法,此處對(duì)此演示
* 這里user.getTime返回的是time這個(gè)Date對(duì)象的引用,因此d調(diào)用setTime
* 修改的就是time這個(gè)對(duì)象。
*/
public class ReturnValueTest {
public static void main(String[] args) {
User user = new User();
Date d = user.getTime();
System.out.println(d); //Fri Aug 03 17:51:50 CST 2018
d.setTime(1);
System.out.println(user.getTime()); //Thu Jan 01 08:00:00 CST 1970
}
}
class User {
private Date time = new Date();
public Date getTime() {
return time; //可以在這里添加clone,return (Date) time.clone();
}
}
package com.ghw.test;
/**
* java core中提到類中的方法可以訪問(wèn)所屬類的私有特性(屬性或方法)
*/
public class ReturnValueTest {
public static void main(String[] args) {
User user1 = new User();
user1.hello();
}
}
class User {
public void hello() {
helloa();
}
private void helloa() {
System.out.println("helloa");
}
}