1

为什么我们可以更改声明为空白 final 的 hashMap,但不能更改原始类型?例如,如果我创建一张地图

final Map<String, String> someMap;

并在构造函数中对其进行初始化,我仍然可以将值放入其中。但是原始的情况并非如此

final int a;

在这种情况下,我无法更改 a 的值。有人可以解释一下吗?

4

4 回答 4

3

final意味着一旦初始化就无法更改。您只是在声明变量而不是对其进行初始化,因此它是允许的。

所以这样做是有效的

final Map<String, String> someMap;
someMap = new HashMap<String, String>();

但是,如果您尝试在初始化后为其分配另一个值,那么编译器应该会抛出一个错误,即最终变量已经初始化:

    final Map<String, String> someMap;
    someMap = new HashMap<String, String>();
    someMap = new TreeMap<String, String>(); //error here

注意:在 hashmap 中放置/删除值也不会更改最终变量的引用。

于 2013-08-29T08:54:35.043 回答
1

它只是对someMap无法更改的地图的引用(即变量)。地图本身可以更改。例如,您可以插入值。但是您不能将新地图分配给someMap.

于 2013-08-29T08:54:41.790 回答
1

在变量上使用 final 关键字时,您是说该变量只能定义一次。换句话说,一旦一个值被分配给变量,它就不能被重新分配。

这对原始类型产生明显的行为,但对对象不太明显。重要的是,在将值插入地图时,对象实例保持不变。在将对象传递给方法时记住这一点很重要,在使用 get/set/clone 方法时非常重要,因为您可能最终会获得对同一对象的多个引用,其中一个地方的更改(将条目插入地图)可能未定义对他人的影响。

如果您问题中的地图很重要,您可以使用java.util.Collections.unmodifiableMap(m);它来阻止人们摆弄它。

于 2013-08-29T09:00:42.750 回答
1

* emphasized text*当你写:

final Map<String, String> someMap;

重要的是要意识到这someMap是一个参考,并且您将参考声明为最终的。实际对象不是不可变的,但引用是。因此,您不能更改参考,即您不能这样做:

someMap = anotherMap;

稍后的。

于 2013-08-29T09:14:47.793 回答