![](/img/trans.png)
[英]Java Generics: interface method that receives type argument of implementing class
[英]Passing interface type (not implementing class type) as argument in java
我正在開發一個“服務提供商”(非常類似於Google果汁)。 它的工作是將任意class_1或接口映射到可以實例化的 * class_2 *,並實現class_1(如果class_1是接口 )或/ extends class_1(如果class_1不是接口)。
所以目前我有方法
public <T> void map(Class<T> key, Class<? extends T> service)
代碼的問題是我可以將接口類型映射到接口類型
ServiceProvider sp = new ServiceProvider();
sp.map(IParent.class, IChild.class);
這完美編譯沒有錯誤(IChild擴展IParent)。 當然,后來當我想:
IParent obj = sp.getService(IParent.class); //look for IParent mapping and instantiate the proper object
我收到java.lang.InstantiationException。
所以問題是:
如何聲明map()方法,以便編譯器檢查第二個參數是實現或擴展第一個參數的類而不是接口? ( 關鍵是要得到編譯時錯誤 。我已經知道如何在運行時檢查這個)
謝謝。 PS:是的 - 搜索了很多,幾乎沒有發現。
UPD:感謝您的所有時間。 關於這一切的可能還有更多的話:目標是開發機制(ServiceProvider類),這將幫助我避免在我的應用程序中緊密耦合,硬依賴。 所以我已經開發/采用了以下理念:“如果你想提供'單位'( 可重復使用的軟件) - 宣布所有公共接口;實施是你的私人業務,我們根本不關心;如果有人想要要使用你的單元,他們應該從ServiceProvider請求它1.在啟動時他們使用sp.map(IYuorInterface.class,TheClassImplementingIt.class); 2. IYuorInterface obj = sp.getService(IYuorInterface.class);你負責make TheClassImplementingIt類'instantiatable'(構造函數,安全性,類不是抽象等);如果不是 - 可以獲得運行時異常。
有什么好處?
很明顯 - 在任何給定時間,任何其他開發人員都可以重新實現IYuorInterface映射它與ServiceProvider,然后所有應用程序將使用它而無需更改單行代碼。 (最簡單的情況是需要它 - 單元測試)
所以我的觀點/問題是:map()方法中的第二個參數必須是Class類型,它表示一個Class,而不是Interface,它應該與第一個參數“賦值兼容”。
換句話說,當我做map(ISomeIterface.class,Something.class)時; Something的對象 (實例)應該像這樣使用:
ISomeIterface obj = sp.getService(ISomeIterface.class);
//or in other words, just for example -- the Something can be used like this:
ISomeIterface obj = new Something();
這就是為什么工廠,如某些答案所暗示的那樣是不可接受的,ServiceProvider類已經是一種“工廠”了
..而且似乎Java的Class對象同時代表了類和接口,並且在編譯時沒有辦法區分真正的類或接口。
但無論如何 - 感謝所有人。
您可以找出Class是否是一個具體的,可實例化的類使用
public boolean isConcrete(Class<?> input)
{
if (input.isInterface())
return false;
if (Modifier.isAbstract(input.getModifiers()))
return false;
return true;
}
據我所知,如果Class
對象代表一個instanciable類,則無法在編譯時檢查。
即使在類的情況下,它也可能是抽象的,或者它可能缺少無參數的構造函數。
作為替代方案,我建議您使用Factory對象而不是類本身。
如果不是第二個參數,你可以通過一個工廠。
interface IInterface{
void go();
}
class IInterfaceImpl implements IInterface{
public void go(){}
}
interface Factory<T>{
T createInstance();
}
class FactoryImpl implements Factory<IInterface>{
@Override
public IInterface createInstance() {
//you need to return an instance of IInterface, which can only be a class
return new IInterfaceImpl();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.