对具有接口类和类型变量的 Java 交叉类型的限制

Jen*_*ens 5 java types jls

今天,我尝试编写一个具有使用交集类型的泛型方法的类,并被根据相交类型的不同错误消息弄糊涂了。假设我们有 aninterface和 aclass并在泛型接口中定义泛型方法:

class ClassType {
}

interface InterfaceType {
}

interface I<T> {
    public <X extends InterfaceType & InterfaceType> void foo();

    public <X extends ClassType & ClassType> void foo1();

    public <X extends ClassType & InterfaceType> void foo2();

    public <X extends InterfaceType & ClassType> void foo3();

    public <X extends T & ClassType> void foo4();

    public <X extends ClassType & T> void foo5();

    public <X extends InterfaceType & T> void foo6();

    public <X extends T & InterfaceType> void foo7();
}
Run Code Online (Sandbox Code Playgroud)

编译此代码会导致所有方法出错,除了public <X extends ClassType & InterfaceType> void foo2();.

Main.java:8: error: repeated interface
    public <X extends InterfaceType & InterfaceType> void foo();
                                      ^
Main.java:10: error: interface expected here
    public <X extends ClassType & ClassType> void foo1();
                                  ^
Main.java:14: error: interface expected here
    public <X extends InterfaceType & ClassType> void foo3();
                                      ^
Main.java:16: error: a type variable may not be followed by other bounds
    public <X extends T & ClassType> void foo4();
                          ^
Main.java:18: error: unexpected type
    public <X extends ClassType & T> void foo5();
                                  ^
  required: class
  found:    type parameter T
  where T is a type-variable:
    T extends Object declared in interface I
Main.java:20: error: unexpected type
    public <X extends InterfaceType & T> void foo6();
                                      ^
  required: class
  found:    type parameter T
  where T is a type-variable:
    T extends Object declared in interface I
Main.java:22: error: a type variable may not be followed by other bounds
    public <X extends T & InterfaceType> void foo7();
                          ^
7 errors
Run Code Online (Sandbox Code Playgroud)

由于交集应该是对称的,我很惊讶foo2被接受但foo3被拒绝。为什么会受理这一案件?

我也想知道为什么在涉及交叉类型时接口、类和类型参数之间存在区别。我可以看到在一个交叉类型中不允许超过一个类的原因,但当前状态接受ClassType & InterfaceType但不InterfaceType & ClassType似乎奇怪地任意。A & A也禁止交叉,但这在语义上与A所以我没有看到这样做的原因。

我也很好奇为什么在交集中不允许类型变量。最坏的情况是两个或更多类的交集,但只是一个无人居住的类型,所以是底部类型。

isa*_*ace 2

你只能有 1 个类,但有多个接口。如果您有一个类,它必须是第一个指定的类。如果遵循此规则,则不应出现任何编译错误。

请参阅https://docs.oracle.com/javase/tutorial/java/generics/bounded.html