Я хотел бы лучше понять, что произойдет, когда компилятор 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 что-то говорит об этом, и ни одна из информации, которую я нашел в Google, не охватывает эту тему.