它实际上相当简单。
基本上就是说不...
1- 提供对您的对象可能包含的任何可变对象的任何引用。
因此,如果您Class
包含 ajava.util.List
作为其字段之一,则任何使用您的客户都无法通过减速或某种获取器Class
直接获得对该字段的引用。List
public
例如...
public class BadImmutableExample {
public List<String> myStrings; // This can not be referenced by the client
/*...*/
}
会很糟糕,因为myStrings
任何机构都可以访问该字段以进行修改...
例如,如果您必须返回 in 中的值,则List
要么需要返回 的副本List
(而不是对它的引用),要么返回值的数组。
例如...
public class BadImmutableExample {
private List<String> myStrings; // This can not be referenced by the client
/*...*/
public List<String> getMyStrings() {
return myStrings;
}
}
将向任何客户公开List
myStrings
,这将允许他们修改它。
在这种情况下,您还可以使用Collections.unmodifiableList(myStrings)
使列表不可修改,return new ArrayList<String>(myStrings)
或者返回一个数组String
而不是...
2-永远不要将这样的字段初始化为客户提供的对象......
基本上这意味着,如果您Class
要求客户为其提供某种或多种价值,您永远不应该直接维护它们的引用,而是再次制作副本供您自己参考......
例如...
public class BadImmutableExample {
private List<String> myStrings; // This can not be referenced by the client
public ImmutableExample(List<String> clientStrings) {
myStrings = clientStrings;
}
}
会打破这条规则,因为任何更改clientStrings
都会立即反映在你的课堂上。
相反,您可以执行类似...
public class BetterImmutableExample {
private List<String> myStrings; // This can not be referenced by the client
public ImmutableExample(List<String> clientStrings) {
myStrings = new ArrayList<String>(clientStrings);
}
}
相反,它将制作客户提供的列表的副本,但不再反映对其所做的更改(客户提供的列表)