Why final instance class variable in Java?

后端 未结 11 698
南方客
南方客 2020-12-09 05:13

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; 
         


        
相关标签:
11条回答
  • 2020-12-09 05:37

    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
    
    0 讨论(0)
  • 2020-12-09 05:42

    Note:- When you declare an object reference as final, it means that it will always point to the same object on heap to which it was initialized.

    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?

    1.) Java is pass by value so when you write cc.setConditionMap(cacheMap) where cacheMap is an object reference (Note:- cacheMap is not an object itself, it is just a reference) then you are just passing the address of the object on heap to setConditionMap(cacheMap), now inside setConditionMap(cacheMap), conditionMap is initialized with the value of cacheMap(the value of cache Map is the address of Map Object). Now after this step both conditionMap and cacheMap refers to the same object on heap. But the catch is that you can again set the value of conditionMap so that it points to some other map object on heap but cacheMap will always point to the same Map Object.

    2.) Declaring a variable as final doesn't means that object on heap is final(doesn't makes sense at all, right?) instead what it means is that it variable will always point to the object to which it was initialized and nobody can change it.

    0 讨论(0)
  • 2020-12-09 05:43

    Let's say, final Map map = new HashMap(); new : is responsible to create object in heap which holds value

    "map" reference will be created in stack which is final.

    The value of "map" reference is real object created in heap.
    As "map" reference is final, it can not have any other value in it.
    
    When we pass "map" reference, Actually we pass the value of map which is nothing but reference of object created in heap. In the called method, another
    reference "map" will be created in stack which holds the same reference of object in heap.
    
    The same concept is coded in this example
    

    import java.util.HashMap; import java.util.Map;

    public class FinalExample { public static void main(String[] args) {

        // Please see this example in case of normal variable and go through the
        // comment
        Final1 f1 = new Final1();
        f1.fun2();
    
        // Please see this example in case of Map Object and go through the
        // comment
        Final2 f2 = new Final2();
        f2.fun2();
    
    }
    

    }

    class Final1 { final int a = 10;

    void fun1(int a) {
        a += 20;
        System.out.println(a);
    }
    
    void fun2() {
    
        // Here we are passing just content of final variable "a" but not the
        // block "a" itself.
    
        // When method fun1 is called another local block "a" will be created
        // This local "a" has nothing to do with instance final "a". Both are
        // different
        // We can change the value of local a it has nothing to do with instance
        // "a"
    
        fun1(a);
    }
    

    }

    class Final2 { final static Map map = new HashMap();

    static {
        map.put("1", "Nandeshwar");
        map.put("2", "Sah");
    }
    
    void fun1(Map map) {
        map.put("3", "John");
        map.put("4", "Nash");
    
        System.out.println(map);
    }
    
    void fun2() {
    
        // Here (in fun1) we pass the content of final map. The content of final
        // map is
        // the refernece of real object which holds the value
        // "1" "Nandeshwar // "2" "Sah".
    
        // When we call fun1, Another object "map(Map)" will be created. this
        // newly created object "map" will also
        // indicate the same reference as instance map refers
    
        // So the local object "map" and instance object "map" both is
        // different. But indicates the real Object which holds the value
        fun1(map);
    }
    

    }

    0 讨论(0)
  • 2020-12-09 05:45

    As the other answers have specified, you cannot make a final variable refer to another object.

    Quoting from the Java Language Specification:

    4.12.4. final Variables

    A final variable may only be assigned to once... 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.

    That rule isn't being violated in the edited portion of your question:

    • You've declared CacheMap as final, and you're not reassigning a new value to it anywhere. If you'd be able to do that, it would be a violation.

    • cachemapdeclaredasfinal only refers to the same thing that CacheMap is referring to, and is not final itself.

    As Suresh has mentioned upthread, it would help if you read up on values and references in Java. A good starting point is this thread: Is Java "pass by reference"?. Make sure you understand why Java is always pass-by-value and never pass-by-reference - that's the reason why the "finalness" of CacheMap wasn't getting passed around.

    0 讨论(0)
  • 2020-12-09 05:45

    This question might help you: http://www.stackoverflow.com/questions/40480/is-java-pass-by-reference

    From what I understand, this is what is actually happening: When you pass an object into a method with java, you're basically passing a pointer to the object. As such, when you call cc.geConditionMap(), you're basically getting the pointer back. When you change it, you're not actually changing the object. You are making your copy of the pointer point to a different map.

    Your copy of the pointer isn't protected by final since you stored the copy to a non-final variable.

    0 讨论(0)
提交回复
热议问题