简体   繁体   中英

Initializing a final variable in java by calling a method

Following is the code that initializes the final variable.

class MyClass{

    public final int x = newMethod1();

    public int newMethod1(){
        return 10;
    }

}

The code above complies and runs fine. My question is when we declare a variable as final we need to initialize it in the same line with a constant value. Now the method will be called dynamically in short the variable is not initialized in the conventional way, or is it? Why no compilation error us thrown here?

when we declare a variable as final we need to initialize it in the same line with a constant value

No you don't. You just can't reassign it after initializing it. You don't even need to initialize it on the line of its declaration.

In java if you used final before premitive variable that means once it assigned, it can not be reasaigned.

Ex. final int a=5;

Second point if you use final before reference type then its assigned object can not be changed.

Ex. final Animal animal=new Dog();

animal = new Cow();// you cant do it
animal.color="white";// you can do it

In your case you are assigning final variable only once. So compiler is not giving any error.

Declaring a variable final just means that the object can be initialized only once, doesn't matter when. This is particularly useful when you want to ensure that someone doesn't overrides it's value by mistake. Also, it helps compiler perform better in some cases, this answer might interest you. To describe what I said this is a perfectly valid way to use the final keyword.

final String var;
if(condition){
    var = "some value";
} else{
    var = "some other value";
}

when we declare a variable as final we need to initialize it in the same line with a constant value

A counter-example would be:

public class QuickTest {

    private final int x;
    {
        x = 5;
    }

    private final static int y;
    static {
        y = 5;
    }

    public QuickTest() {
    }
}

I do this sometimes when I want to set a final field with multiple lines of code (ie not just a single method call). These {} enclosures also allows me the opportunity to wrap everything in a proper try-catch if I want to. Remember, in your example - if #newMethod1() threw an error then your class would fail to instantiate. Just an example to illustrate:

public class QuickTest {

    private final int x;
    {
        try {
            int someCalculation = 5 + 3;
            someCalculation += 10;

            // set it
            x = someCalculation;
        } catch (Exception e) {
            // handle exception if we can
            ;

            // unrecoverable error, so let the calling code fail :(
            // LogManager.error(this, e);
            throw new RuntimeException(e);
        }
    }

    public QuickTest() {
    }
}

A link to the Java spec on final HERE

Final variable is constant and value can not be reassigned to it. Either we can declare the final variable is at class label or we can declare it as method/block label.

First one is , if are declaring any final variable as class label variable then you have to initialize it at the first line of variable declaration itself. Because compiler thinks that this class label variable might get used anywhere in the class and if it is not initialized at the time of declaration itself then if it gets used anywhere it will lead to exception. For safer side compiler will force you to declare it.

Second one is if you are declaring any final variable inside any method/initialization block etc then you can declare the method without initializing it. Because variables scope is local to that block and it's chance of getting used else where is not possible. So compiler will not force you to initialize it.

Now coming to your question, calling the method is just to initialize the final variable. So compiler will not give error for that, cause you are doing what compiler wants you to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM