I’ve come across some odd behavior in assignment of final variables. You can assign a final varible in a constructor to initialize it, which makes sense. However you can’t do the same in a subclass, even if the final variable is a member of the subclass –
public class FinalTest {
public final String name;
public FinalTest()
{
name = "FinalTest";
}
public static class FinalTestSubclass extends FinalTest {
public FinalTestSubclass()
{
name = "FinalTestSubclass"; //<---- this won't compile, assignment to final variable.
}
}
}
Can someone think of a good reason why this should/would work this way?
Every constructor of a subclass must invoke a constructor of the superclass as its first operation. Every final member variable must be initialized before a constructor completes. A final variable can be assigned only once. Given those rules, it is impossible for a subclass constructor to directly assign a value to a
finalsuperclass’ member.Making exceptions would increase complexity and create “gotchas” in exchange for limited additional utility.
A practical solution is to provide a superclass constructor that takes a value to be assigned to the final member. This can be
protectedor package-private if desired. If the superclass is outside of your control, there’s a good chance that allowing derived classes to break its assumptions about the finality of its members would cause other problems.