2014-11-09 148 views
0

我知道我正在嘗試做的事情對於純java來說並不是真的可行 - 只有當我查看調試信息時纔有可能。無論如何我都不會編譯,因爲我的spring mvc會停止工作。如何確定泛型超類的特定子類的ACTUAL返回類型?

這麼說,我有以下情況:

一個通用超:

包com.cinefms.apitester.springmvc.crawlers;

public class TestGenerics<T extends TestGenericsInterface> { 

    public T get() { 
     return null; 
    } 

    public T put(T t) { 
     return null; 
    } 

} 

和它的子類:

package com.cinefms.apitester.springmvc.crawlers; 


public class TestGenericsSub extends TestGenerics<TestGenericsImpl> { 

} 

在那裏是真該死簡單的對象。

接口:

package com.cinefms.apitester.springmvc.crawlers; 

public interface TestGenericsInterface { 

} 

和它的實現:

package com.cinefms.apitester.springmvc.crawlers; 

public class TestGenericsImpl implements TestGenericsInterface { 

} 

日食是完全沒有搞清楚是的TestGenericsSub.get()應返回的TestGenericsImpl實例......即使沒有源可用。

但我怎麼可能在運行時自己弄清楚這一點?

如果 「M」 是方法 「運行」,然後

m.getGenericReturnType(); 

將返回 「T」(沒有用),而:

m.getReturnType(); 

給我 「TestGenericsInterface」(也未有用)。我一直在看「org.javaruntype」庫...但我似乎無法弄清楚。

有人可以解釋嗎?

謝謝!

+0

你不能,在一般情況下,判斷ACTUAL返回類型的方法,而不檢查方法中的代碼(通用與否)。最好你可以確定方法聲明中指定的FORMAL返回類型(使用適當的泛型swizzle),但該方法總是可以返回該類型的子類。 – 2014-12-04 20:29:06

回答

0

可以實現與ClassMate

TypeResolver typeResolver = new TypeResolver(); 
MemberResolver memberResolver = new MemberResolver(typeResolver); 

ResolvedType resolvedType = typeResolver.resolve(TestGenericsSub.class); 
ResolvedTypeWithMembers resolvedTypeWithMembers = memberResolver.resolve(resolvedType, null, null); 
ResolvedMethod resolvedGetMethod = resolvedTypeWithMembers.getMemberMethods()[0]; 

System.out.println(resolvedGetMethod.getReturnType()); // TestGenericsImpl 
+0

是的,這幾乎是我一直在尋找的東西。我發現在org.javaruntime中很難做到 - 在那裏,我可以獲得所有必要的信息,但是我必須自己解決超類的泛型變量 - 真的有點痛苦。感謝指針! – rmalchow 2014-11-09 15:29:39

0

感謝Java類型擦除(https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html),這是相當困難的。我建議保存類當成一個屬性,然後提供一個getter如果你絕對必須知道T的運行時類型

public class MyGenericClass<T> { 

    private final Class<T> type; 

    public MyGenericClass(Class<T> type) { 
     this.type = type; 
    } 

    public Class<T> getMyType() { 
     return this.type; 
    } 
} 

否則,你可以嘗試這樣的:

(Class<T extends TestGenericsInterface>) ((TestGenerics) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 

我會在代碼中更喜歡前者的解決方案。

+0

嗨。事情是,我實際上在對其他人的代碼進行反省。特別是,我試圖從Spring MVC控制器此信息,: \t https://github.com/rmalchow/spring-api-tester \t ,所以我不能實際控制的代碼。一般來說,我同意。 – rmalchow 2014-11-09 15:26:29

0

TypeTools是另一種選擇:

Class<?> t = TypeResolver.resolveRawArgument(TestGenerics.class, TestGenericsSub.class); 

如預期的結果:

assert t == TestGenericsImpl.class;