2011-05-05 109 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

我不相信你可以做到這一點沒有反思。

看來你應該做的並不是使用靜態方法。您正在使用繼承,但靜態方法不遵循繼承規則。