2014-03-12 33 views
0

我有以下的類/接口設置。使用java.lang.Class作爲方法參數的問題

  • 接口IFoobar
  • 類的BaseClass它實現IFoobar和是抽象
  • 類ConcreteClassA延伸的BaseClass
  • 類ConcreteClassB延伸的BaseClass
  • 類ConcreteClassC延伸的BaseClass

我有一個方法,我需要傳遞上述具體的java.lang.Class的實例類。我是這樣宣佈的。

void doSomething(String id, Class<IFoobar> c) 

然而,當我嘗試編譯,用java錯誤抱怨或多或少是這樣的:

doSomething(java.lang.String,java.lang.Class<IFoobar>) in javaclass cannot be applied to 
     (java.lang.String,java.lang.Class<ConcreteClassA>) 
     register("12345", ConcreteClassA.class); 
     ^
1 error 

我是最近才需要使用java.lang.Class中做的事情,所以我猜我缺少一些簡單的東西。我希望類型化的類聲明能夠像普通參數一樣工作,因爲具體類被識別爲接口的實例,但這顯然不是這種情況。

我試過了鑄造等各種方法,要麼沒有預期的結果,要麼有無效的代碼。所以任何想法,我需要做什麼,將不勝感激。

在此先感謝。

+0

你怎麼能得到 「類」 的實例?你的意思是你想要傳遞任何類的對象嗎? –

回答

2

Class<IFoobar>類型的變量只能容納一個Class<IFoobar>對象,而不是Class<ConcreteClassA>對象的引用。

更改Class<IFoobar>Class<? extends IFoobar>

此行爲對於Class對象不是特別明智。這是更符合邏輯的集合,它阻止你這樣做:

void method1(List<IFoobar> list) 
{ 
    list.add(new ConcreteClassA()); 
} 

void method2() 
{ 
    List<ConcreteClassB> list = /* something */; 
    method1(list); 
    // oops! we put a ConcreteClassA inside a List<ConcreteClassB> 
} 
+0

謝謝@immibis,看起來已經解決了這個問題。我絕不是一位泛型專家,但我將其解讀爲「任何擴展(或在本例中實現)IFoobar的類」,對嗎? – user3404036

+0

是的。爲了泛型的目的,'implements'和'extends'都被稱爲'extends' - Class <?實施IFoobar>'是無效的。就像我說過的,當你想到集合庫使用它們的方式時,泛型更合乎邏輯,而不是'Class'使用它們的方式。有很好的理由你爲什麼要'List <?擴展IFoobar>'或'List ',但是沒有很好的理由使用'Class '而不是'Class <?擴展IFoobar>'。 – immibis

0

Class<IFoobar>的唯一可接受值爲IFooBar.class。如果你想接受IFooBar.class及其所有子類,你應該使用Class<? extends IFooBar>

0

錯誤無關與「類」

簡單,如果你使用

ArrayList<Object> x = new ArrayList<String>(); 

你得到錯誤:不兼容的類型

因爲雖然String類是Object的子類ArrayList < Object>是與ArrayList不同的類型<字符串>。這就是泛型的本質。

您可以使用

void doSomething(String id, Class c) 
+0

Thanks @Chamil,我正在考慮使用它,但希望確保傳遞給該方法的'Class'實例是實現IFoobar接口的實例。通過使用類,我希望我可以傳遞比預期更廣泛的對象。 – user3404036

相關問題