最终的奇怪的java分配规则

Ste*_* B. 2 java

我在最终变量的分配中遇到了一些奇怪的行为.您可以在构造函数中指定最终变量来初始化它,这是有道理的.但是,即使最终变量是子类的成员,您也无法在子类中执行相同操作 -

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.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有人会想到这个应该/会以这种方式运作的一个很好的理由吗?

eri*_*son 11

子类的每个构造函数都必须调用超类的构造函数作为其第一个操作.必须在构造函数完成之前初始化每个最终成员变量.最终变量只能分配一次.根据这些规则,子类构造函数不可能直接将值赋给final超类的成员.

制造例外将增加复杂性并创建"陷阱"以换取有限的额外效用.

一个实际的解决方案是提供一个超类构造函数,它将值赋给最终成员.protected如果需要,这可以是包或私有的.如果超类超出了你的控制范围,那么允许派生类打破其成员最终性的假设很有可能会导致其他问题.


mat*_*t b 6

如果允许您为其分配值name,FinalTestSubClass则意味着分配的值FinalTest实际上不是最终值.

如果你的例子是有效的,那么这意味着name可能有不同的值(基于实例化的类),使得final修饰符非常多余.

一个更好的问题是,为什么允许你想要的行为?