2012-07-10 203 views
0

比方說,我有這些類:Java泛型和通配符

class A<T> { 
    void set(T t) {} 
} 

class B<T> { 
    T get() { return null; } 
} 

class C extends A<String> { } 
class D extends B<String> { } 

class E extends A<Long> { } 
class F extends B<Long> { } 

而且這些變量:

A<?> a1 = new C(); 
B<?> b1 = new D(); 

A<?> a2 = new E(); 
B<?> b2 = new F(); 

我可以做這些莫名其妙地(有一些魔術?):

a1.set(b1.get()); 
a2.set(b2.get()); 

回答

4

不可以,但你可以做

A<String> a1 = new C(); 
B<String> b1 = new D(); 

A<Long> a2 = new E(); 
B<Long> b2 = new F(); 

a1.set(b1.get()); 
a2.set(b2.get()); 

A<?>指一些類的A,但我不知道是哪一個。所以你不能調用它的set()方法,因爲編譯器不知道參數的類型是否與A的實際泛型類型相匹配。

0

您想將1種對象轉換爲另一種對象。嘗試adapter pattern。請查看維基鏈接瞭解適配器模式的更多內容。

創建一個適配器類,將您的對象B時,要變換B向A對象A

class MyAdapter 
{ 


public static A adaptTo(B b) 
{ 
//your code to transform B to A 

} 

} 

現在,只需撥打

A a = Adapter.adaptTo(b); 
+1

翻譯在哪裏? 'b1.get()'返回一個字符串,'a1.set()'接受一個字符串。 – 2012-07-10 10:42:36

+0

@PeterLawrey他必須在適配器類方法中實現該邏輯。 – 2012-07-10 10:44:54

+0

爲什麼他需要如果類型是相同的? – 2012-07-10 10:45:50

3

你不能因爲你有

A<?> a1 = new C(); 
B<?> b1 = new D(); 

相同
A<? extends Object> a1 = new C(); 
B<? extends Object> b1 = new D(); 

所以泛型類型a是通配符或未知。 b1.get()是Object,a1.set()接受Object的未知子類。

A<String> a1 = new C(); 
B<String> b1 = new D(); 
a1.set(b1.get()); // is okay as the type is `String` 
+0

我試圖用A z =(A )a1; z.set(b1.get())似乎工作。這會導致任何問題嗎? – jaakko 2012-07-10 11:00:58

+0

如果你不關心類型安全性,爲什麼要使用泛型?這樣做基本上與刪除泛型類型相同,並接受任何類型的對象作爲參數。 – 2012-07-10 11:09:23

+0

那麼,這是我的問題,如果我可以做到(安全)沒有類型安全,對不起,有點不清楚。所以,沒有類型安全,我可以按照我想要的方式來做。只是現有的API返回通配符。 – jaakko 2012-07-10 11:13:38