3

我有一个带有静态字段 F 的 A 类:

class A {
    public static String F = null;
}

B类:

class B extends A {
   public static String F = "somestring";
} 

和一个使用字段 F 的方法的类型化类:

class C<T extends A> {
   public void someMethod() {
      String someString = T.F;
      // Manipulations with someString
   }
}

然后是我调用它的代码。

C<B> c = new C<B>();
c.someMethod();

并且在尝试使用 someString 进行操作时出现空指针异常。所以,TF 是 null,但 T 是 B,所以它应该是“somestring”!为什么?

4

4 回答 4

7

您不能覆盖字段。由于它是扩展 A,它将始终使用 A 中的字段。

在类 A 和 B 中添加一个返回 F 的 getter。从那里,用 B 中的方法覆盖 A 中的方法。

class A {
    public String getF(){
        return null;
    }
}

class B {
    @Override
    public String getF(){
        return "someString";
    }
}
于 2013-02-07T20:14:41.583 回答
2

这与泛型无关。

类的字段不能被子类覆盖——只有方法可以。因此,即使您在子类中定义了一个与超类中同名的字段,您也只是创建了一个新字段,该字段恰好具有相同的名称,但实际上隐藏(而不是覆盖)前一个字段。

考虑在子类的构造函数中使用字段的默认值进行赋值。然后它应该工作。

于 2013-02-07T20:15:38.173 回答
2

Java 中的静态成员可以隐藏,但不能被覆盖。对静态成员的引用在编译时解析 - 在编译时,唯一已知的 T 类型是 A。

请参阅http://www.coderanch.com/how-to/java/OverridingVsHiding

编辑:一个字段无论如何都不能被覆盖,无论它是静态的还是实例的。

于 2013-02-07T20:24:48.967 回答
1
  1. 发生这种情况是因为 的所有static成员A都是A单独的,不能被 继承B

  2. 没有出现在 中的新static成员不能出现在AB

  3. 实际上,当你说

    class C < T extends A > { ... }

您只能使用方法(静态和实例 - 除非@Overriden)和A. 因此,由于F不是实例字段,因此它不会被覆盖,并且 JVM 会F在 A 中找到 的出现。

因此,您获得了 NPE。

于 2013-02-07T20:26:21.947 回答