2010-09-15 74 views
4

我有一個看起來像這樣Java通用方法在運行時轉換爲參數類型,有可能嗎?

public static <T extends MyClass, X extends AnotherClass> List<T> (Class<T> aParameter, X anotherParameter) 

現在如果AnotherClass是一個抽象類,不具有的getId定義的方法,但擴展了此接口做的每一個類。 (不要問我爲什麼它被設計這是爲什麼呢,我沒有設計的抽象類,而我不能改變它)。

我怎樣才能做這樣的事情

anotherParameter.getId(); 

我知道我必須將它轉換爲類,但後來我不得不做一切可能的類的instanceof檢查,然後投放。

所以,正確的知道我有類似:

if (anotherParameter instanceof SomeClass) 
    ((SomeClass)anotherParameter).getId(); //This looks bad. 

是否可以動態地施放此?到任何anotherParameter在運行時?

回答

5

你能修改派生類嗎?如果是這樣,你可以定義這個(語法可能是錯誤的)的接口:

 
public interface WithId { 
    void getId(); 
} 
... 
public class MyDerivedClass1 extends AnotherClass implements WithId { 
... 
} 
... 
public class MyDerivedClass2 extends AnotherClass implements WithId { 
... 
} 

,然後,你的方法裏面做:

 
... 
if (anotherParameter instanceof WithId) { 
WithId withId = (WithId) anotherParameter; 
withId.getId(); 
} 
... 

如果你可以改變你的方法的簽名,也許你可以指定一個intersection type

public static <T extends MyClass, X extends AnotherClass & WithId> List<T> myMethod(Class<T> aParameter, X anotherParameter)

,然後你就會有你的滿足內部getId()直接提供HOD。

+0

注比的不是實現WithId,你可以1)代碼的抽象類'AnotherClassWithId'提供'抽象無效的getId()'2)使你的派生類擴展的是,和3)使你的方法參數'anotherParameter'是輸入'AnotherClassWithId'。這會更簡單,並且對代碼的更改只需更少,但基本思路是相同的。 – gpeche 2010-09-15 18:11:17

+0

謝謝你工作得很好。 – 2010-09-15 22:41:34

3

我會說不,因爲由於類型擦除,X實際上只是Object在運行時。你可以嘗試做一些與反思,以測試anotherParameter有getId()如果是這樣,調用它。

2

鑄造在運行時的東西好好嘗試一下真正的意義,因爲你有一個實例,它可以告訴你它是什麼類的概念。您將需要使用反射,例如使用Introspector類。

private Integer getId(final X anotherParameter) { 
    final BeanInfo beanInfo = Introspector.getBeanInfo(anotherParameter.getClass()); 
    for (MethodDescriptor methodDescriptor : beanInfo.getMethodDescriptors()) { 
     final Method method = methodDescriptor.getMethod(); 
     if ("getId".equals(method.getName()) 
       && method.getParameterTypes().length == 0) { 
      return (Integer) method.invoke(anotherParameter); 
     } 
    } 
    return null; 
} 
2

您可以使用反射在運行時要調用的方法,如果它存在。

try { 
    Method m = anotherParameter.getClass().getMethod("getId", null); 
    Object result = m.invoke(anotherParameter, null); 
} 
catch (NoSuchMethodException e) { 
    // ... and several other exceptions need to be caught 
} 
1

正如其他人在這裏所說的那樣,反射是唯一可行的解​​決方案,但是我會通過緩存反射元數據(可能是由類+ methodName鍵入的映射)來增強這一點,因爲那部分反射isn完全便宜。你不能幫助「調用()」部分。

相關問題