java - 为什么在 Java 中使用 final 实例类变量?

标签 java final

如果实例变量设置为final,那么它的值就不能像

public class Final {

    private final int b;

    Final(int b) {
        this.b = b; 
    }

    int getFinal() {
        return  b = 8;  // COMPILE TIME ERROR 
    }
}


在代码的某处,我看到实例类变量 HashMap 声明为 final

 private  final Map<String, Object> cacheMap = new HashMap<String, Object>();

我不明白为什么要这样声明?通常在这种情况下它被声明。这是否意味着一旦我放入 HashMap 就无法更改它的值?

编辑:
如果将声明为 final 的 cacheMap 作为参数传递给另一个类,那么如果我更改其引用,则不会为 final 显示错误。为什么会这样?

 class CacheDTO {

    private Map conditionMap;

    public Map getConditionMap() {
        return conditionMap;
    }

    public void setConditionMap(Map conditionMap) {
        this.conditionMap = conditionMap;
    }
}

然后

private  final Map<String, Object> cacheMap = new HashMap<String, Object>();
CacheDTO cc = new CacheDTO();
cc.setConditionMap(cacheMap);
Map<String, Object> cacheMapDeclaredAsFinal = cc.getConditionMap();
Map<String, Object> newMap = new HashMap<String, Object>();
cacheMapDeclaredAsFinal = newMap;    // In this case no error is shown. Though cacheMapDeclaredAsFinal reference is obtained by calling cc.getConditionMap() and cacheMapDeclaredAsFinal refers to final.

最佳答案

您无法更改篮子。还是可以换里面的水果。

来自 Language specification # chapter 14.12.4

Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object.

当您声明一个 fieldreference final 时,您必须在构造函数退出时设置一次值。

您只能在构造函数中为该变量赋值。

 private  final Map<String,Object> CacheMap = new HashMap<String,Object>();

在这里你可以做

CacheMap.put(.....  

在类里面。

但是你做不到

CacheMap =   something.  //compile error.

你应该知道 valuereference 的区别。

编辑

这里

 Map<String, Object> cachemapdeclaredasfinal = cc.geConditionMap();

 Map<String, Object> newMap = new HashMap<String, Object>();

 cachemapdeclaredasfinal  = newMap; // In this case no error is shown

原因,

因为 cachemapdeclaredasfinal 不是新 map ,所以它是 conditionMap 的另一个引用

当你像这样创建一个新实例时

   Map<String, Object> cachemapdeclaredasfinal =
                                new HashMap<String, Object>(cc.geConditionMap());

该错误消失了。因为您使用了

编辑 2:

 private Map conditionMap;

 public void setConditionMap(Map ConditionMap) {
        this.conditionMap = conditionMap;
    }
  private  final Map<String, Object> CacheMap = new HashMap<String, Object>();
  CacheDto cc = new CacheDto();
  cc.setConditionMap(CacheMap);
  Map<String, Object> cachemapdeclaredasfinal = cc.geConditionMap();
  Map<String, Object> newMap = new HashMap<String, Object>();
 cachemapdeclaredasfinal  = newMap;

这是你混淆的地方。

您正在将一个声明为 finalmap 分配给一些普通的(非 final)map。当您检索到该法线时,您得到的不是 final,因此您可以进一步使用/分配

简而言之

normalMap= finalMap; //no error since normalMap is not final
finalMap =normalMap;// compiler error since normalMap is final

关于java - 为什么在 Java 中使用 final 实例类变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19049697/

相关文章:

java - 清除并重绘 Eclipse 插件项目中的 View

java - 线程中的最终字段语义

java - 我应该将静态工厂方法设为 final方法吗?

java - 如何将字符串拆分为包含值列表的映射?

java - 使用PreparedStatement自动递增

java - 在保留键盘上的回车图标的同时,对 EditText 执行操作在 android 中按下回车?

java - 从 for 循环打印元素

Java - 从内部类内部访问变量

java - 有什么方法可以使 A 类的变量只能被特定接口(interface)的类修改吗?

java - 为什么我们不能在 INTERFACE 的静态 block 内分配变量?奥卡