【问题标题】:Blank final with Reference type带有参考类型的空白最终
【发布时间】:2013-08-29 08:52:47
【问题描述】:

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

final Map<String, String> someMap;

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

final int a;

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

【问题讨论】:

标签: java collections map hashmap final


【解决方案1】:

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 中放置/删除值也不会改变最终变量的引用。

【讨论】:

  • 但在原语的情况下不允许这样做?
  • 原语是保存值的数据类型,而引用就像指针,它不保存它们的值,而是指向它们的值,并在对象上/与对象一起使用。如果你理解了这部分,那么你也会明白为什么你可以放一个最终的 hashMap 参考。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

      *emphasized text*当你写的时候:

      final Map<String, String> someMap;
      

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

      someMap = anotherMap;
      

      稍后。

      【讨论】:

        猜你喜欢
        • 2015-05-22
        • 2021-11-14
        • 2019-04-13
        • 1970-01-01
        • 2019-06-20
        • 1970-01-01
        • 2021-08-19
        • 2012-12-26
        • 1970-01-01
        相关资源
        最近更新 更多