Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why final instance class variable in Java?

Tags:

java

final

If instance variable is set final its value can not be changed like

public class Final {

    private final int b;

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

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


Somewhere in code I have seen instance class variable HashMap declared as final

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

I could not understand why it is declared so? Normally in which case it is declared. Does it mean if once I put in hash map then I could not change its value?

Edit:
If cacheMap which is declared as final is passed as parameter to another class then error is not shown for final if I change its reference. Why it is so?

 class CacheDTO {

    private Map conditionMap;

    public Map getConditionMap() {
        return conditionMap;
    }

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

Then

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.
like image 788
abishkar bhattarai Avatar asked Sep 27 '13 11:09

abishkar bhattarai


1 Answers

You can't change the Basket. Still you can change the fruits inside.

From 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.

When you declare a field or reference final, you must set the value once by the time the constructor exits.

You can assign a value to that variable only in constructor.

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

here you can do

CacheMap.put(.....  

with in the class.

but you cannot do

CacheMap =   something.  //compile error.

You should know the difference between value and reference.

Edit

Here

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

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

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

Reason ,

Since cachemapdeclaredasfinal is not a new map it's another reference of conditionMap

when you create a new instance like this

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

That error disappears. since you used new.

Edit 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;

Here you what you confused is.

You are assigning one final declared map to some normal(non final) map. When you retrieved that normal only you are getting and that not final so you can use/assign it further.

In Short

normalMap= finalMap; //no error since normalMap is not final
finalMap =normalMap;// compiler error since normalMap is final
like image 55
Suresh Atta Avatar answered Sep 24 '22 03:09

Suresh Atta