在上一节,我们使用简单的ML小例子,说明了编程语言中无可变性的好处。下面我们使用java语言编写的小例子来进一步体会。
下面代码会有java安全性问题(糟糕的代码)
class ProtectedResource {
private Resource theResource = ...;
private String[] allowedUsers = ...;
public String[] getAllowedUsers() {
return allowedUsers;
}
public String currentUser() { ... }
public void useTheResource() {
for(int i=0; i < allowedUsers.length; i++) {
if(currentUser().equals(allowedUsers[i])) {
... // access allowed: use it
return;
}
}
throw new IllegalAccessException();
}
}
通过阅读上面的代码,可以知道因为java允许“可变性”的存在,资源“theResource”能被任何人访问到,而不论该“user”是否在“allowedUsers”数组里面。
说明:
通过调用方法“getAllowedUsers”得到“allowedUsers”数组的别名(或引用);然后将该数组的第一个元素使用当前用户替换掉,我们就可以访问到资源“theResource”了。
p.getAllowedUsers()[0] = p.currentUser();
p.useTheResource();
修复
在支持可变性的语言中,可以在恰当的地方复制可能会被重新赋值的绑定,是一个防止可变性副作用的常用预防手段。
public String[] getAllowedUsers() {
… // return a copy of allowedUsers
}