Setting the attribute of the final class

Is it possible to set the value for the final attribute from a private method called from the constructor of this object?

public class FinalTest { private final Object a; //Constructor public FinalTest() { setA(); } private void setA() { a = new Object; } } 

For the above class, the compiler gives me an error saying that I cannot set the value for 'a' from the method.

I understand that it is impossible to set the value for the final variable from outside the constructor, but in this case I actually do it in the constructor. So why is this not allowed?

+4
source share
4 answers

This is not allowed because you could call setA() through some other non-constructor method, which would later violate the final defense. Since final is a forced compilation operation, the compiler forces final to force initialization to occur in constructors or in strings.

In your simple example, everything looks good, but if you later updated your class to the next, the problem will become more obvious ...

 public class FinalTest { private final Object a; //Constructor public FinalTest() { setA(); } private void setA() { a = new Object; } public void doSomething() { this.setA(); // not good because a is final } } 
+10
source

Just a note: the compiler must accept the worst case scenario. By declaring the attribute "final", the compiler must ensure that the attribute cannot be changed outside the constructor.

In the case when the method is called using reflection (for example), the compiler will never see it. It is much easier to prove that something is possible than impossible, so the compiler works the way it does.

+2
source

The final check is performed at compile time not at run time. In your case, the compiler cannot be sure that setA will not be called by any other method.

+1
source

Why do you need to set the value of the final variable from a private method? You can do it as follows:

 public class FinalTest { private final Object a; { a=new Object(); } //Constructor public FinalTest() { } } 

In this case, the object will be initialized each time FinalTest is initialized.

+1
source

Source: https://habr.com/ru/post/1347104/


All Articles