1.定义:什么是表示泄露,举个例子
class Poem {
public String title;
public String author;
private List<String> lines = new ArrayList<>();
private Date date;
在这个Poem类中我们定义了四个属性,对其中的lines我们有如下方法修改
public void addOneLine(String newLine) {
lines.add(newLine);
}
我们期望用户都调用我们所设计的方法来增添诗文。但是因为我们的lines的权限修饰是public,
导致外部可以直接取用我们内部的rep来改变它,如下:
public static void main(String[] args) {
final List<String> lines = new ArrayList<>();
lines.add("Happpy");
lines.add("Birthday");
Poem p = new Poem("100th", "HHH", lines, new Date());
System.out.println(p.lines);
p.lines.add("error");
System.out.println(p.lines);
}
这便是表示泄露:在java编程中,我们实现某个类时,每个类都定义一些域。有immutable的例如String,有mutable的例如list,set。而我们在构造观察器的时候如果不对mutable类型的变量进行表示处理,就容易在外部对内部的类属性进行修改,而我们正常则应该需要调用内部方法才能对内部属性进行修改。
2.如何防止表示泄露
(1)最简单的方法就是将我们rep的域由public改为private
(2)在写get方法(observer方法)时,注意防御式编程
例子:
将这种代码
public List<String> getAllLines() {
return lines;
}
改成
public List<String> getAllLines() {
return new ArrayList<>(lines);
}
不要直接返回你的rep本体,否则这样同样会导致表示泄露