2011-12-28 79 views
0

我想创建一个只接受特定类的容器。使用泛型如下:Java泛型:通配符

static class Test1<C extends Test1> { 
      C field = null; 
      public C getField() { 
       return field; 
      } 
      public void setField(C field) { 
       this.field = field; 
      } 
     } 
     static class Test2 extends Test1{ 
     } 

class MainTest { 
      public static void main(String[] args) throws Exception { 
       List<Test1<? extends Test1>> list = new ArrayList<Test1<? extends Test1>>(); 
       Test1<Test2> newInstance = new Test1<Test2>(); 
       list.add(newInstance); 
       Test1<Test2> value = list.get(1); 
    } 
} 

只是想了解为什么这个名单>愿意接受的newInstance对象,但编译时错误,而我取“的Test1值”后发生? 是否有任何解决该问题的机会?

在此先感谢。

UPDATE 许多人注意到“Test1<? extends Test1>,其中?可能不等于Test2”。 我完全同意,但据我所知,在这种情况下,我需要键入提取的值到Test1<Test2>,这意味着在这种情况下泛型的全部内容都会丢失......如果我错了,请纠正我。

+0

你为什么不宣布名单的'名单> list'? – BalusC 2011-12-28 15:38:47

+0

'Test1 '是'Test1 <?扩展Test1 >',但Test1 <?扩展Test1 >'不是'Test1 '的一个实例。 (你也有罕见的类型 - 混合的通用类型和原始类型 - 这是个坏消息。) – 2011-12-28 15:41:14

+0

我希望列表包含Test1的所有组合,其中包含它的任何后代。 – user1119571 2011-12-28 15:41:47

回答

1

因为当你list.get(1)返回Test1<? extends Test1>,其中?可能不等于Test2

一方面list.add(...)接受Test1<? extends Test1>,即Test1带有任何泛型参数,它是Test1的继承者。

+0

那么你是说类型转换是解决问题的唯一方法?但是在这种情况下,使用泛型的全部观点都会丢失...... – user1119571 2011-12-28 15:43:37

+0

这不是泛型的一点。 – BalusC 2011-12-28 17:13:03

+0

泛型的要点是确保设计时的类型安全,如果我错了,请纠正我的错误。如果是这样,那么类型转换基本上就是毁了整个想法。很高兴听到你的考虑。 – user1119571 2011-12-28 18:49:59

0

这是因为您可以将Test1的子项的每个对象作为输入参数来存储Test1 <>。比方说,你有 类Test3的扩展测试1 那么你就必须

Test1<Test2> value = list.get(1); 

但名单将如何确保与指数1元素有一个通用型的Test2但不Test3的,因为它接受的Test1的每一个亚型( )。

获取元素的正确方法是使用

Test1<? extends Test1> test1 = list.get(1); 
0

您可以通过编写

Test1<? extends Test1> value = list.get(1); 

代替

Test1<Test2> value = list.get(1); 

或者通过强制转换为Test1的解决问题。

+0

而之后,我应该typecaset Test1 ? – user1119571 2011-12-28 15:47:04

0
List<Test1<? extends Test1>> list = new ArrayList<Test1<? extends Test1>>(); 

这是一个只读列表,你只能插入空这份名单,没有别的

下面改用:

List<Test1<? extends Test1>> list = new ArrayList<Test1<XXX>>(); where XXX extends Test1