请考虑以下两个类和接口:
public class Class1 {}
public class Class2 {}
public interface Interface1 {}
如果mandatory
和Class2
与getInterface1
没有关系,为什么对Interface1
的第二个调用为什么用Class2
调用重载方法?
public class Test {
public static void main(String[] args) {
Class1 class1 = getClass1();
Interface1 interface1 = getInterface1();
mandatory(getClass1()); // prints "T is not class2"
mandatory(getInterface1()); // prints "T is class2"
mandatory(class1); // prints "T is not class2"
mandatory(interface1); // prints "T is not class2"
}
public static <T> void mandatory(T o) {
System.out.println("T is not class2");
}
public static <T extends Class2> void mandatory(T o) {
System.out.println("T is class2");
}
public static <T extends Class1> T getClass1() {
return null;
}
public static <T extends Interface1> T getInterface1() {
return null;
}
}
我了解Java 8 broke compatibility与Java 7:
$ /usr/lib/jvm/java-8-openjdk-amd64/bin/javac -source 1.7 -target 1.7 *java; /usr/lib/jvm/java-8-openjdk-amd64/bin/java Test
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning
T is not class2
T is not class2
T is not class2
T is not class2
并且使用Java 8(也已通过11和13测试:)
$ /usr/lib/jvm/java-8-openjdk-amd64/bin/javac *java; /usr/lib/jvm/java-8-openjdk-amd64/bin/java Test
T is not class2
T is class2
T is not class2
T is not class2
Java编译器假定可能存在扩展Class2
并实现Interface1
的类:
public class Class3 extends Class2 implements Interface1 {}
因此,它决定getInterface1()
返回与public static <T extends Class2> void mandatory(T o)
签名匹配的对象:
mandatory(Test.<Class3>getInterface1()); // T is class2
在mandatory(Test.<T>getInterface1())
处得到相同结果的情况下调用T extends Class2 & Interface1
:>
public static <T extends Class2 & Interface1> void helper() { mandatory(Test.<T>getInterface1()); // T is class2 }
mandatory(getClass1())
不会一样,因为Class3
不能同时扩展Class1
和Class2
。