你能指定一个泛型类型,它继承另一个泛型类型_and_具体的接口吗?

Sle*_*led 15 java generics

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

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

class C{}
class D extends C implements Cloneable{}
Run Code Online (Sandbox Code Playgroud)

我想创建一个通用类型签名来强制执行此配对,我试过这个失败:

<T1,T2 extends T1 & Cloneable> void f ( T1 t1, T2 t2 ){}
Run Code Online (Sandbox Code Playgroud)

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

<T1,T2 extends Cloneable & T1> void f ( T1 t1, T2 t2 ){}
Run Code Online (Sandbox Code Playgroud)

我收到了消息 "Interface expected here."

令人困惑的是,这两个签名WORK:

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

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

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

ysh*_*vit 6

答案在JLS 4.4中:

TypeParameter:
    TypeVariable TypeBoundopt

TypeBound:
    extends TypeVariable
    extends ClassOrInterfaceType AdditionalBoundListopt

AdditionalBoundList:
    AdditionalBound AdditionalBoundList
    AdditionalBound

AdditionalBound:
    & InterfaceType
Run Code Online (Sandbox Code Playgroud)

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

所以,是的,它是Java通用语法的限制.