假设:
public class Base {
public static final String FOO = "foo";
public static void main(String[] args) {
Base b = new Base();
Sub s = new Sub();
System.out.print(Base.FOO); // <- foo
System.out.print(Sub.FOO); // <- bar
System.out.print(b.FOO); // <- foo
System.out.print(s.FOO); // <- bar
System.out.print(((Base)s).FOO); // <- foo
}
}
class Sub extends Base {
public static final String FOO="bar";
}
我怀疑在第8行和第9行我们使用引用变量来访问类的静态成员......是否可能?因为静态成员只能通过类名访问...请纠正我错在哪里?
答案 0 :(得分:5)
我要去选项D.
静态成员在编译时使用声明的类型解析,而不是实际类型。
这就是((Base)s).FOO)
引用Base.FOO
的原因 - 即使对象是Sub
。
这也会发生,并在下面更好地说明:
Base b = new Sub(); // valid
System.out.print(b.FOO); // foo
此处b.FOO
引用Base.FOO
,因为声明了类型,即使该实例是Sub
。
答案 1 :(得分:3)
有可能吗?
是的,这是可能的,虽然不是一个好的做法。基本上,在字段上访问静态成员将在编译时解析为对声明的字段类型的访问。
例如,即使是以下情况也可以正常工作:
class Test {
public static String hello = "Hello";
}
Test test = null;
System.out.println(test.hello);
print语句不会像第一次看到的那样抛出NPE
。因为访问有效地解决了:
Test.hello
由于声明的test
类型为Test
,因此以这种方式解析了访问权限。
现在,由于静态字段访问是在编译时使用声明的类型解析的,因此您不会看到静态方法的多态行为。它就像是,你不能覆盖静态方法。
答案 2 :(得分:1)
静态成员也可以通过实例访问。
IMO这是一种不良行为,因为它具有误导性/无意识性。
事实上,您可以使用null
引用,例如
Base base = null;
System.out.println(base.FOO);
答案 3 :(得分:1)
你可以通过引用访问静态变量。 但是正常情况下你应该从你的编译器那里得到警告......
答案 4 :(得分:0)
静态变量可以通过类名和引用来访问。请参阅Access static variable from object in Java