2011-05-05 159 views
1

我想访问一个类的静态方法,但该类传递一个通用的。通用类的访问静态方法

我已经做了以下内容:

class Base{ 
    public static String getStaticName(){ 
    return "Base"; 
    } 
} 


class Child extends Base{ 
    public static String getStaticName(){ 
    return "Child"; 
    } 
} 

class StaticAccessor{ 
    public static <T extends Base>String getName(Class<T> clazz){ 
    return T.getStaticName(); 
    } 
} 

StaticAccessor.getName() // --> "Base" 

这将返回“基地”但我想是“儿童”人无反光有何建议?

回答

9

因为T类型在运行时被删除(意思是它将减少到其下限,即Base),所以不能这样做。

既然你有权访问Class<T>你可以用反射做到这一点,但是:

return (String) clazz.getMethod("getStaticName").invoke(null); 

注意,我会考虑这样的代码是代码的气味,这是相当脆弱的。你能告诉我们为什么你需要吗?

+1

简单:return clazz.getSimpleName(); – 2011-05-05 12:24:55

+0

@Nathan:是的,*如果*实现将总是如此。 – 2011-05-05 12:25:28

+0

正确。我的建议只有在getStaticName()方法的意图是返回类的简单(或二进制/规范)名称时才起作用。 – 2011-05-05 12:33:23

0

如果它是确定你在你的静态访问传递一个对象实例,而不是类的话,有一个简单而优雅的解决方案:

public class Test { 

    static class Base { 
     public static String getStaticName() { return "Base"; } 
     public String myOverridable() { return Base.getStaticName(); }; 
    } 

    static class Child extends Base { 
     public static String getStaticName() { return "Child"; } 
     @Override 
     public String myOverridable() { return Child.getStaticName(); }; 
    } 

    static class StaticAccessor { 
     public static <T extends Base>String getName(T instance) { 
      return instance.myOverridable(); 
    } 

} 


    public static void main(String[] args) { 

     Base b = new Base(); 
     Child c = new Child(); 

     System.out.println(StaticAccessor.getName(b)); 
     System.out.println(StaticAccessor.getName(c)); 

    } 

} 

输出是:

Base 
Child 
+0

是的,这只是使用多态性来获得名称。最初的例子似乎暗示它应该在没有任何对象实例的情况下工作,并且只针对类。我想在这个例子中,你可以在对象实例本身上调用getName方法。 – planetjones 2011-05-05 14:08:24

+0

@planetjones不,你不能在实例本身上调用getStaticName(),因为它只会在两种情况下返回'Base'。 – JVerstry 2011-05-05 14:12:56

+0

哦对不起,我打算说,反对对象调用方法,即可以直接调用myOverridable()对b或c。 – planetjones 2011-05-05 14:14:38

0

我不相信你可以做到这一点没有反思。

看来你应该做的并不是使用静态方法。您正在使用继承,但静态方法不遵循继承规则。