Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Complaint against final variable

Tags:

java

final

Okay, so as far as I know, I understand these things about a final variable.

  1. It should be assigned only once
  2. All the final variables should be initialized before the constructor completes

Now using the above, I do not understand how the below doesn't work:

public class FinalTest implements AnotherClass {

    private final Something something;
    private final otherthing;

    @Override
    public void setStuff(Something something) {
        this.something = something;
        this.otherthing = new SomeClass(something);
    }

    public FinalTest(Something something) {
        setStuff(something);
    }
}

Here, before the constructor completes the final variables are being set. So why does the compiler complain against it?

like image 613
noMAD Avatar asked Nov 20 '12 17:11

noMAD


People also ask

What will happen if variable is final?

Final variables If a variable is declared with the final keyword, its value cannot be changed once initialized.

Is final variable can be changed?

The only difference between a normal variable and a final variable is that we can re-assign the value to a normal variable but we cannot change the value of a final variable once assigned.

When should variable be final?

The term effectively final variable was introduced in Java 8. A variable is effectively final if it isn't explicitly declared final but its value is never changed after initialization.

Should local variables be final?

Method parameters and local variables should not be declared final unless it improves readability or documents an actual design decision. Fields should be declared final unless there is a compelling reason to make them mutable.


1 Answers

It's not necessary that your method gets called only from constructor, it can be called from outside your constructor also. And even a second call might be added to the same constructor in future also.

Even though you might not have used it now, but Compiler cannot be sure about it, so it does not allow it. In technical term, there is no definite assignment.

For e.g: - suppose you instantiate your class from main: -

public static void main(String[] args) {
    FinalTest obj = new FinalTest(something);

    obj.setStuff(something); // There you go. This cannot be prevented. 
}

See JLS - Definite Assignments for detailed explanation on this.

like image 125
Rohit Jain Avatar answered Oct 09 '22 10:10

Rohit Jain