How does the “final” keyword in Java work? (I can still modify an object.)

前端 未结 18 2320
醉酒成梦
醉酒成梦 2020-11-22 03:08

In Java we use final keyword with variables to specify its values are not to be changed. But I see that you can change the value in the constructor / methods of

相关标签:
18条回答
  • 2020-11-22 03:18

    This is a very good interview question. Sometimes they might even ask you what is the difference between a final object and immutable object.

    1) When someone mentions a final object, it means that the reference cannot be changed, but its state(instance variables) can be changed.

    2) An immutable object is one whose state can not be changed, but its reference can be changed. Ex:

        String x = new String("abc"); 
        x = "BCG";
    

    ref variable x can be changed to point a different string, but value of "abc" cannot be changed.

    3) Instance variables(non static fields) are initialized when a constructor is called. So you can initialize values to you variables inside a constructor.

    4) "But i see that you can change the value in the constructor/methods of the class". -- You cannot change it inside a method.

    5) A static variable is initialized during class loading. So you cannot initialize inside a constructor, it has to be done even before it. So you need to assign values to a static variable during declaration itself.

    0 讨论(0)
  • 2020-11-22 03:22

    Suppose you have two moneyboxes, red and white. You assign these moneyboxes only two children and they are not allowed interchange their boxes. So You have red or white moneyboxes(final) you cannot modify the box but you can put money on your box.Nobody cares (Modification-2).

    0 讨论(0)
  • 2020-11-22 03:22

    When you make it static final it should be initialized in a static initialization block

        private static final List foo;
    
        static {
            foo = new ArrayList();
        }
    
        public Test()
        {
    //      foo = new ArrayList();
            foo.add("foo"); // Modification-1
        }
    
    0 讨论(0)
  • 2020-11-22 03:25

    This is a favorite interview question. With this questions, the interviewer tries to find out how well you understand the behavior of objects with respect to constructors, methods, class variables (static variables) and instance variables.

    import java.util.ArrayList;
    import java.util.List;
    
    class Test {
        private final List foo;
    
        public Test() {
            foo = new ArrayList();
            foo.add("foo"); // Modification-1
        }
    
        public void setFoo(List foo) {
           //this.foo = foo; Results in compile time error.
        }
    }
    

    In the above case, we have defined a constructor for 'Test' and gave it a 'setFoo' method.

    About constructor: Constructor can be invoked only one time per object creation by using the new keyword. You cannot invoke constructor multiple times, because constructor are not designed to do so.

    About method: A method can be invoked as many times as you want (Even never) and the compiler knows it.

    Scenario 1

    private final List foo;  // 1
    

    foo is an instance variable. When we create Test class object then the instance variable foo, will be copied inside the object of Test class. If we assign foo inside the constructor, then the compiler knows that the constructor will be invoked only once, so there is no problem assigning it inside the constructor.

    If we assign foo inside a method, the compiler knows that a method can be called multiple times, which means the value will have to be changed multiple times, which is not allowed for a final variable. So the compiler decides constructor is good choice! You can assign a value to a final variable only one time.

    Scenario 2

    private static final List foo = new ArrayList();
    

    foo is now a static variable. When we create an instance of Test class, foo will not be copied to the object because foo is static. Now foo is not an independent property of each object. This is a property of Test class. But foo can be seen by multiple objects and if every object which is created by using the new keyword which will ultimately invoke the Test constructor which changes the value at the time of multiple object creation (Remember static foo is not copied in every object, but is shared between multiple objects.)

    Scenario 3

    t.foo.add("bar"); // Modification-2
    

    Above Modification-2 is from your question. In the above case, you are not changing the first referenced object, but you are adding content inside foo which is allowed. Compiler complains if you try to assign a new ArrayList() to the foo reference variable.
    Rule If you have initialized a final variable, then you cannot change it to refer to a different object. (In this case ArrayList)

    final classes cannot be subclassed
    final methods cannot be overridden. (This method is in superclass)
    final methods can override. (Read this in grammatical way. This method is in a subclass)

    0 讨论(0)
  • 2020-11-22 03:25

    The final keyword indicates that a variable may only be initialized once. In your code you are only performing one initialization of final so the terms are satisfied. This statement performs the lone initialization of foo. Note that final != immutable, it only means that the reference cannot change.

    foo = new ArrayList();
    

    When you declare foo as static final the variable must be initialized when the class is loaded and cannot rely on instantiation (aka call to constructor) to initialize foo since static fields must be available without an instance of a class. There is no guarantee that the constructor will have been called prior to using the static field.

    When you execute your method under the static final scenario the Test class is loaded prior to instantiating t at this time there is no instantiation of foo meaning it has not been initialized so foo is set to the default for all objects which is null. At this point I assume your code throws a NullPointerException when you attempt to add an item to the list.

    0 讨论(0)
  • 2020-11-22 03:26

    Worth to mention some straightforward definitions:

    Classes/Methods

    You can declare some or all of a class methods as final, in order to indicate that the method cannot be overridden by subclasses.

    Variables

    Once a final variable has been initialized, it always contains the same value.

    final basically avoid overwrite/superscribe by anything (subclasses, variable "reassign"), depending on the case.

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