15

我有一系列域模型,每个模型都有一个扩展它实现特定接口的子类,如下所示(Cloneable不是有问题的接口,仅用于示例目的):

class A{}
class B extends A implements Cloneable{}

class C{}
class D extends C implements Cloneable{}

我想创建一个通用类型签名来强制执行这种配对,我已经尝试过这个FAILS

<T1,T2 extends T1 & Cloneable> void f ( T1 t1, T2 t2 ){}

但我在 IntelliJ IDE 中收到消息"Type parameter cannot be followed by other bounds";如果我将订单切换到以下位置,它仍然会失败:

<T1,T2 extends Cloneable & T1> void f ( T1 t1, T2 t2 ){}

我收到消息"Interface expected here."

令人困惑的是,这两个签名都有效

<T extends A & Cloneable> void f( A a, T t ){}
<T1,T2 extends T1> void f ( T1 t1, T2 t2 ){}

这是否只是 Java 泛型类型系统的一个奇怪限制,即我不能让泛型类​​(即T2)扩展另一个泛型类(即T1具体接口(例如Cloneable)?

tl; dr:那么,为什么不<T1,T2 extends Cloneable & T1> void f ( T1 t1, T2 t2 ){}编译:这是 Java 通用语法的限制还是我使用了错误的语法?

4

2 回答 2

6

答案在JLS 4.4中:

TypeParameter:
    TypeVariable TypeBoundopt

TypeBound:
    extends TypeVariable
    extends ClassOrInterfaceType AdditionalBoundListopt

AdditionalBoundList:
    AdditionalBound AdditionalBoundList
    AdditionalBound

AdditionalBound:
    & InterfaceType

& Cloneable是 AdditionalBound,只能在 AdditionalBoundList 中使用。AdditionalBoundList 只能在 ClassOrInterfaceType 之后使用。并且T1是 TypeVariable,而不是 ClassOrInterfaceType。

所以,是的,这是 Java 通用语法的限制。

于 2013-11-14T17:37:08.643 回答
0

<T1,T2 extends Cloneable & T1> void f ( T1 t1, T2 t2 ){}

我收到消息“此处需要接口”。

jls 4.4。类型变量:

每个声明为类型参数的类型变量都有一个界限。如果没有为类型变量声明边界,则假定为 Object。如果声明了边界,则它包括:

- a single type variable T, or

- a class or interface type T possibly followed by interface types `I1 & ... & In`.

如果任何类型I1 ... In 类型或类型变量,则会出现编译时错误。

所以,对于一个表达式<T extends C & I> void test(T t)I应该是一个接口。

于 2013-11-14T17:44:34.733 回答