2012-07-10 131 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