2013-02-07 52 views
3

我有静态域F类A:BT和继承在Java中

class A { 
    public static String F = null; 
} 

类别:

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操作时出现空指针异常。所以,T.F是null,但T是B,所以它应该是“somestring”!为什么?

回答

7

您不能覆盖字段。既然是延伸的,它总是会使用领域A.

在一个与一个在加入A类和B返回F.从那里一个getter,重写方法B.

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

class B { 
    @Override 
    public String getF(){ 
     return "someString"; 
    } 
} 
2

这与泛型没有关系。

一个类的字段不能被子类覆盖 - 只有方法可以。所以,即使你在你的子类中定义了一个与超类中的字段相同的字段,你也只是创建了一个新字段,它只是恰好有相同的名字,但实际上是阴影(而不是覆盖)前一个字段。

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

2

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

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

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

1
  1. 这是因为所有的Astatic成员共同独自A,不能由B继承。

  2. 没有新的static成员,它不存在于A中,可以存在于B中。

  3. 实际上,当你说

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

您只能使用方法(包括静态和实例 - 除非@Override n)和它是常见的A领域。因此,由于F不是实例字段,因此它不会被覆盖,并且JVM会在A中发现F

因此,您将得到一个NPE。