在使用findbug檢查代碼時,發現了EI_EXPOSE_REP警告:
[EI] May expose internal representation by returning reference to mutable object [EI_EXPOSE_REP]
原代碼:
private String[] name;
public String[] getName() {
return name;
}
public void setName(String[] name) {
this.name = name;
}
大緻意思說get方法傳回可變對象的話會影響類的封裝性,可以被外部修改。
由此引出了java中對可變對象、不可變對象的概念:
-
可變類和不可變類(Mutable and Immutable Objects)的初步定義:
可變類:當你獲得這個類的一個執行個體引用時,你可以改變這個執行個體的内容。
不可變類:當你獲得這個類的一個執行個體引用時,你不可以改變這個執行個體的内容。不可變類的執行個體一但建立,其内在成員變量的值就不能被修改。
-
如何建立一個自己的不可變類:
.所有成員都是private
.不提供對成員的改變方法,例如:setXXXX
.確定所有的方法不會被重載。手段有兩種:使用final Class(強不可變類),或者将所有類方法加上final(弱不可變類)。
.如果某一個類成員不是原始變量(primitive)或者不可變類,必須通過在成員初始化(in)或者get方法(out)時通過深度clone方法,來確定類的不可變。
- 一個示例
import java.util.Date;
public final class BrokenPerson
{
private String firstName;
private String lastName;
private Date dob;
public BrokenPerson( String firstName, public BetterPerson( String firstName,
String lastName, Date dob) String lastName, Date dob)
{ {
this.firstName = firstName; this.firstName = firstName;
this.lastName = lastName; this.lastName = lastName;
this.dob = dob; //error this.dob = new Date( dob.getTime() ); //correct
} }
public String getFirstName()
{
return this.firstName;
}
public String getLastName()
{
return this.lastName;
}
public Date getDOB() public Date getDOB()
{ {
return this.dob; //error return new Date( this.dob.getTime() );//correct
} }
}
4. jdk的可變類和不可變類
primitive變量: boolean,byte, char, double ,float, integer, long, short
jdk的不可變類:jdk的java.lang包中 Boolean, Byte, Character, Double, Float, Integer, Long, Short, String.
StringBuffer 可變類
java.util.Date 可變類