2010-12-15 154 views
11

我想提供这样的事情在我的API:嵌套泛型泛型类

class Foobar extends AbstractThing<Double> 

class EventThing<Foobar> {  
      public Foobar getSource(); 
      public Double getValue(); 
} 

所以我写这篇文章:

class EventThing<T extends AbstractThing<U>> {  
     public T getSource(); 
     public U getValue(); 
} 

但Java无法解决U

使用EventThing<T extends AbstractThing<U>,U>代替它可以工作,但第二个U实际上是多余的,因为AbtractThing已经定义了类型。所以我喜欢摆脱它。

回答

26

你不能摆脱它。第二个U不是多余的。您希望编译器将第一个U解释为类型参数,但不是。你还可以这样写的:

class EventThing<T extends AbstractThing<Double>> 

注意Double在这种情况下,是一个具体的类,而不是一个类型参数。请将其与以下内容进行比较:

class EventThing<T extends AbstractThing<U>> 

请注意,这与上面第一行代码的形式完全相同。编译器应该如何知道在第一种情况下,Double是指具体类,而在第二种情况下,U是指类型参数?

编译器无法知道该问题,并将U视为具体类,就像第一行中的Double一样。让编译器的唯一途径知道U是一个类型参数是指定它是这样:

class EventThing<T extends AbstractThing<U>, U> 
+1

在我看来,更像是编译器的功能缺失。 编辑: 但我明白你的意思,谢谢你的回答。 要坏。我想我会离开这个洞的功能。 – 2010-12-15 16:31:32

+4

@Marcel:我认为这个答案很清楚地解释了为什么编译器不能(也不应该)试图猜测'U'是一个实际类型还是一个泛型类型参数。 Java要求每个泛型类型参数都有明确的声明。不管你看起来如何,这不是“编译器缺少的功能”。 – ColinD 2010-12-15 17:10:06

+1

@ColinD:我同意Marcel的看法,它确实看起来像是一个缺失的特征,在他的例子中U看起来多余。显然,编译器必须被告知U是一个类型参数,我们可以有这样的类:class EventThing >,本质上是说:U是一个变量类型参数,现在自己去推断它(使用字符%仅供讨论之用,我同意这很丑陋)。这样在调用代码中就不会有重复。 – Gilead 2012-11-28 11:48:39