今天,我尝试编写一个具有使用交集类型的泛型方法的类,并被根据相交类型的不同错误消息弄糊涂了。假设我们有 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所以我没有看到这样做的原因。
我也很好奇为什么在交集中不允许类型变量。最坏的情况是两个或更多类的交集,但只是一个无人居住的类型,所以是底部类型。
你只能有 1 个类,但有多个接口。如果您有一个类,它必须是第一个指定的类。如果遵循此规则,则不应出现任何编译错误。
请参阅https://docs.oracle.com/javase/tutorial/java/generics/bounded.html