Reputation: 4053
Is it possible to set a value for a final attribute from a Private method called from the Constructor of that Object?
public class FinalTest {
private final Object a;
//Constructor
public FinalTest() {
setA();
}
private void setA() {
a = new Object;
}
}
For the above class, compiler gives me an error saying I can't set the value for 'a' from the method.
I understand that its not possible to set value for a final variable from outside a constructor, but in the above case, I am actually doing it in a way within the constructor. So why isn't this allowed?
Upvotes: 5
Views: 4407
Reputation: 31
Just a note: The compiler has to assume the worst case scenario. By declaring an attribute "final", the compiler has to ensure that the attribute cannot be modified outside of the constructor.
In a case where the method is called using reflection (for example), the compiler would never see it, ever. It's a lot easier to prove something is possible than impossible, that is why the compiler works the way it does.
Upvotes: 3
Reputation: 7941
Why do you need to set the value of final variable from a private method ? You may do it in this way :
public class FinalTest {
private final Object a;
{
a=new Object();
}
//Constructor
public FinalTest() {
}
}
In this case the object will be initialized on every FinalTest initialization.
Upvotes: 1
Reputation: 53496
It's not allowed because you could call setA()
via some other non-constructor method later on which would violate the final protection. Since final is a compile time enforced operation, the compiler enforces final by forcing initialization to occur in constructors or in-line.
In your simple example, all looks good but if you later updated your class to something like the following, the problem 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
}
}
Upvotes: 10
Reputation: 3454
Final checking is done at compile time not at runtime time. In your case compiler can't be sure that setA would not be called from some other method.
Upvotes: 1