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

前端 未结 18 2295
醉酒成梦
醉酒成梦 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:37

    Following are different contexts where final is used.

    Final variables A final variable can only be assigned once. If the variable is a reference, this means that the variable cannot be re-bound to reference another object.

    class Main {
       public static void main(String args[]){
          final int i = 20;
          i = 30; //Compiler Error:cannot assign a value to final variable i twice
       }
    }
    

    final variable can be assigned value later (not compulsory to assigned a value when declared), but only once.

    Final classes A final class cannot be extended (inherited)

    final class Base { }
    class Derived extends Base { } //Compiler Error:cannot inherit from final Base
    
    public class Main {
       public static void main(String args[]) {
       }
    }
    

    Final methods A final method cannot be overridden by subclasses.

    //Error in following program as we are trying to override a final method.
    class Base {
      public final void show() {
           System.out.println("Base::show() called");
        }
    }     
    class Derived extends Base {
        public void show() {  //Compiler Error: show() in Derived cannot override
           System.out.println("Derived::show() called");
        }
    }     
    public class Main {
        public static void main(String[] args) {
            Base b = new Derived();;
            b.show();
        }
    }
    
    0 讨论(0)
  • 2020-11-22 03:38

    Read all the answers.

    There is another user case where final keyword can be used i.e. in a method argument:

    public void showCaseFinalArgumentVariable(final int someFinalInt){
    
       someFinalInt = 9; // won't compile as the argument is final
    
    }
    

    Can be used for variable which should not be changed.

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

    The final keyword can be interpreted in two different ways depending on what it's used on:

    Value types: For ints, doubles etc, it will ensure that the value cannot change,

    Reference types: For references to objects, final ensures that the reference will never change, meaning that it will always refer to the same object. It makes no guarantees whatsoever about the values inside the object being referred to staying the same.

    As such, final List<Whatever> foo; ensures that foo always refers to the same list, but the contents of said list may change over time.

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

    If you make foo static, you must initialize it in the class constructor (or inline where you define it) like the following examples.

    Class constructor (not instance):

    private static final List foo;
    
    static
    {
       foo = new ArrayList();
    }
    

    Inline:

    private static final List foo = new ArrayList();
    

    The problem here is not how the final modifier works, but rather how the static modifier works.

    The final modifier enforces an initialization of your reference by the time the call to your constructor completes (i.e. you must initialize it in the constructor).

    When you initialize an attribute in-line, it gets initialized before the code you have defined for the constructor is run, so you get the following outcomes:

    • if foo is static, foo = new ArrayList() will be executed before the static{} constructor you have defined for your class is executed
    • if foo is not static, foo = new ArrayList() will be executed before your constructor is run

    When you do not initilize an attribute in-line, the final modifier enforces that you initialize it and that you must do so in the constructor. If you also have a static modifier, the constructor you will have to initialize the attribute in is the class' initialization block : static{}.

    The error you get in your code is from the fact that static{} is run when the class is loaded, before the time you instantiate an object of that class. Thus, you will have not initialized foo when the class is created.

    Think of the static{} block as a constructor for an object of type Class. This is where you must do the initialization of your static final class attributes (if not done inline).

    Side note:

    The final modifier assures const-ness only for primitive types and references.

    When you declare a final object, what you get is a final reference to that object, but the object itself is not constant.

    What you are really achieving when declaring a final attribute is that, once you declare an object for your specific purpose (like the final List that you have declared), that and only that object will be used for that purpose: you will not be able to change List foo to another List, but you can still alter your List by adding/removing items (the List you are using will be the same, only with its contents altered).

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

    Above all are correct. Further if you do not want others to create sub classes from your class, then declare your class as final. Then it becomes the leaf level of your class tree hierarchy that no one can extend it further. It is a good practice to avoid huge hierarchy of classes.

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

    The final keyword in java is used to restrict the user. The java final keyword can be used in many context. Final can be:

    1. variable
    2. method
    3. class

    The final keyword can be applied with the variables, a final variable that has no value, is called blank final variable or uninitialized final variable. It can be initialized in the constructor only. The blank final variable can be static also which will be initialized in the static block only.

    Java final variable:

    If you make any variable as final, you cannot change the value of final variable(It will be constant).

    Example of final variable

    There is a final variable speedlimit, we are going to change the value of this variable, but It can't be changed because final variable once assigned a value can never be changed.

    class Bike9{  
        final int speedlimit=90;//final variable  
        void run(){  
            speedlimit=400;  // this will make error
        }  
    
        public static void main(String args[]){  
        Bike9 obj=new  Bike9();  
        obj.run();  
        }  
    }//end of class  
    

    Java final class:

    If you make any class as final, you cannot extend it.

    Example of final class

    final class Bike{}  
    
    class Honda1 extends Bike{    //cannot inherit from final Bike,this will make error
      void run(){
          System.out.println("running safely with 100kmph");
       }  
    
      public static void main(String args[]){  
          Honda1 honda= new Honda();  
          honda.run();  
          }  
      }  
    

    Java final method:

    If you make any method as final, you cannot override it.

    Example of final method (run() in Honda cannot override run() in Bike)

    class Bike{  
      final void run(){System.out.println("running");}  
    }  
    
    class Honda extends Bike{  
       void run(){System.out.println("running safely with 100kmph");}  
    
       public static void main(String args[]){  
       Honda honda= new Honda();  
       honda.run();  
       }  
    }  
    

    shared from: http://www.javatpoint.com/final-keyword

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