修改 public 静态最终数组
modifying a public static final array
在设计一个小的 API 时,我正要编写一个引用字符串数组的静态值:
public static final String[] KEYS={"a","b","c"}
我发现这在 Joshua Bloch 的 'Effective Java' 项目 14 中被标记为 'security hole',他建议作为替代方案,声明数组 'private' 并提供 public getter returns 一个不可修改的列表:
return Collections.unmodifiableList(Arrays.asList(KEYS))
我只是不明白为什么这是必要的,初始语句中的数组被声明为最终的,即使它 public,并且它的元素是不可变的,如何从外部代码修改它?
最终表示
You can't change the Basket. Still you can change the fruits inside.
Basket 是您的 Array 实例。水果是你里面的钥匙。
在第一种情况下,我可以从代码的其他地方做到
ClassName.KEYS[2] ="MyOwnValue";
但不可修改列表是不能修改的
尝试阅读:Why final instance class variable in Java?
数组不是不可变的。
你还可以写:
KEYS[0] = "d";
没有任何问题。
final
只是意味着你不能写:
KEYS = new String[]{"d"};
即您不能为变量 KEYS
.
分配新值
虽然数组引用本身是不可变的(您不能用对另一个数组的引用替换它)并且字符串本身也是不可变的,但仍然可以编写
KEYS[0] = "new Key";
一个复合对象(数组、Set
、List
等)是 final
并不意味着它的组成对象不会被改变——你仍然可以改变组成对象。 final
对于复合对象仅仅意味着它的引用不能被改变。
对于您的情况,无法更改 KEYS
的值,但可以更改 KEYS[0]
等。
在设计一个小的 API 时,我正要编写一个引用字符串数组的静态值:
public static final String[] KEYS={"a","b","c"}
我发现这在 Joshua Bloch 的 'Effective Java' 项目 14 中被标记为 'security hole',他建议作为替代方案,声明数组 'private' 并提供 public getter returns 一个不可修改的列表:
return Collections.unmodifiableList(Arrays.asList(KEYS))
我只是不明白为什么这是必要的,初始语句中的数组被声明为最终的,即使它 public,并且它的元素是不可变的,如何从外部代码修改它?
最终表示
You can't change the Basket. Still you can change the fruits inside.
Basket 是您的 Array 实例。水果是你里面的钥匙。
在第一种情况下,我可以从代码的其他地方做到
ClassName.KEYS[2] ="MyOwnValue";
但不可修改列表是不能修改的
尝试阅读:Why final instance class variable in Java?
数组不是不可变的。
你还可以写:
KEYS[0] = "d";
没有任何问题。
final
只是意味着你不能写:
KEYS = new String[]{"d"};
即您不能为变量 KEYS
.
虽然数组引用本身是不可变的(您不能用对另一个数组的引用替换它)并且字符串本身也是不可变的,但仍然可以编写
KEYS[0] = "new Key";
一个复合对象(数组、Set
、List
等)是 final
并不意味着它的组成对象不会被改变——你仍然可以改变组成对象。 final
对于复合对象仅仅意味着它的引用不能被改变。
对于您的情况,无法更改 KEYS
的值,但可以更改 KEYS[0]
等。