Java 编译器如何为具有多个边界的参数化类型选择运行时类型?
我想更好地了解当Java编译器遇到对如下方法的调用时会发生什么。
<T extends AutoCloseable & Cloneable>
void printType(T... args) {
System.out.println(args.getClass().getComponentType().getSimpleName());
}
// printType() prints "AutoCloseable"
我很清楚,在运行时没有类型,因此编译器做了它能做的最不错误的事情,并创建了一个数组,其类型为两个边界接口之一,丢弃另一个。<T extends AutoCloseable & Cloneable>
无论如何,如果切换接口的顺序,结果仍然是相同的。
<T extends Cloneable & AutoCloseable>
void printType(T... args) {
System.out.println(args.getClass().getComponentType().getSimpleName());
}
// printType() prints "AutoCloseable"
这导致我做了更多的调查,看看当接口改变时会发生什么。在我看来,编译器使用某种严格的顺序规则来决定哪个接口是最重要的,而接口在代码中出现的顺序没有任何作用。
<T extends AutoCloseable & Runnable> // "AutoCloseable"
<T extends Runnable & AutoCloseable> // "AutoCloseable"
<T extends AutoCloseable & Serializable> // "Serializable"
<T extends Serializable & AutoCloseable> // "Serializable"
<T extends SafeVarargs & Serializable> // "SafeVarargs"
<T extends Serializable & SafeVarargs> // "SafeVarargs"
<T extends Channel & SafeVarargs> // "Channel"
<T extends SafeVarargs & Channel> // "Channel"
<T extends AutoCloseable & Channel & Cloneable & SafeVarargs> // "Channel"
问题:当存在多个边界时,Java 编译器如何确定参数化类型的 varargs 数组的组件类型?
我甚至不确定JLS是否对此有任何看法,而且我通过谷歌搜索找到的信息都没有涵盖这个特定主题。