为什么<T扩展了Enum<T>和SomeInterface>编译,而不是<T扩展了SomeInterface和Enum<T>>?

2022-09-04 07:57:14

我不明白为什么方法2不编译,而方法1编译。我正在将Eclipse与JavaSE 1.7一起使用,并且在方法2上遇到了以下错误:

此行上的多个标记

  • Enum<T>类型不是接口。不能将其指定为有界参数

  • 绑定不匹配:类型 T 不是有界参数的有效替代项<E 扩展 Enum<E>> 类型 Enum<E>

public class Test {

    public interface SomeInterface {

    }

    public static <T extends Enum<T> & SomeInterface> T method1() {
        return null;
    }

    public static <T extends SomeInterface & Enum<T>> T method2() {
        return null;
    }
}

答案 1

如果您查看 JLS 8.1.2 中类型参数边界的语法,您将看到:

TypeBound:
    extends TypeVariable 
    extends ClassOrInterfaceType {AdditionalBound}

AdditionalBound:
    & InterfaceType

换句话说,只有指定的一个类型可以是类 - 其余的都必须是接口。

除此之外,这还可以防止指定多个类。

它还反映了在声明类时,您必须首先放置它所扩展的类,然后放置它实现的接口 - 而不是相反。


答案 2

根据文档

具有多个边界的类型变量是绑定中列出的所有类型的子类型。如果其中一个边界是类,则必须首先指定它。例如:

Class A { /* ... */ }
interface B { /* ... */ }
interface C { /* ... */ }

class D <T extends A & B & C> { /* ... */ }

如果未首先指定绑定 A,则会出现编译时错误:

class D <T extends B & A & C> { /* ... */ }  // compile-time error

由于在您的示例中首先具有接口,因此它显示了编译器错误method2SomeInterface