为什么可以覆盖Java中的最终常量?


Answers

你隐藏它,这是“范围”的一个特点。 任何时候你在一个较小的范围内,你可以重新定义你喜欢的所有变量,并且外部范围变量将被“蒙上阴影”

顺便说一下,如果你喜欢,你可以重新确定范围:

public class A implements I {
    public String KEY = "b";

    public String getKey() {
        String KEY = "c";
        return KEY;
    }
}

现在KEY将返回“c”;

编辑,因为原来吸重读。

Question

考虑Java中的以下接口:

public interface I {
    public final String KEY = "a";
}

和以下班级:

public class A implements I {
    public String KEY = "b";

    public String getKey() {
        return KEY;
    }
}

为什么类A可能会出现并覆盖接口I的最终常量?

为自己而努力:

A a = new A();
String s = a.getKey(); // returns "b"!!!



你不应该以这种方式访问​​你的常量,而应该使用静态引用:

I.KEY //returns "a"
B.KEY //returns "b"



静态字段和方法附加到声明它们的类/接口(尽管接口不能声明静态方法,因为它们是需要实现的完全抽象类)。

所以,如果你有一个公共静态(vartype)(varname)的接口,那么这个字段会被附加到那个接口上。

如果你有一个类实现了这个接口,编译器把戏把这个varname转换成InterfaceName.varname。 但是,如果您的类重新定义了varname,那么将一个名为varname的新常量附加到您的类中,编译器现在知道将(var。)varname转换为NewClass.varname。 同样适用于方法:如果新类不重新定义方法,则将(this。)methodName转换为SuperClass.methodName,否则将(this。)methodName转换为CurrentClass.methodName。

这就是为什么你会遇到这样的警告:“应该以静态方式访问x字段/方法”。 编译器告诉你,尽管它可能会使用这个技巧,但它更喜欢你使用ClassName.method / fieldName,因为为了便于阅读,它更加明确。




Links