Final Variable Complaint

Well, as far as I know, I understand these things about the final variable.

  • It should only be appointed once.
  • All final variables must be initialized before the constructor completes.

Now, using the above, I don't understand how the below works:

 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, final variables will be set. So why does the compiler complain about this?

+7
source share
5 answers

You do not need your method to be called only from the constructor; it can also be called from outside your constructor. And even a second call can be added to the same constructor in the future.

Even if you may not have used it now, but the compiler cannot be sure of it, therefore it does not allow it. In technical terms, there is no definite assignment .

For example, for example:, you create an instance of the 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 - Specific Jobs for more details.

+18
source

Because no one stops you from calling setStuff() for the second time in the life of an object, which would be illegal.

final fields can only be assigned in code blocks that are guaranteed to be executed only once; these are instance constructors and initializers. (Or a static initializer in the case of a static final field.)

You can learn more about this in JLS .

+8
source

because the compiler does not know that the only call

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

- from the designer

+3
source

If the next line will be

 private final otherthing; 

something like

 private final Something otherthing; 

you are missing a class.

0
source

Just a note:

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

This is a really bad design. You should not call the overridable method from the constructor.

0
source

All Articles