Ответ 1
Я могу дублировать эту проблему в Java 7, но когда я переключусь на Java 8, ошибка больше не указана. Кроме того, если я остаюсь в Java 7, но я даю аргумент типа Arrays.asList
, ошибка больше не указана.
List<Class<? extends JComponent>> listComp =
Arrays.<Class<? extends JComponent>>asList(JTabbedPane.class, JPanel.class);
Java попытается определить целевой тип возврата Arrays.asList
. По-видимому, оба JTabbedPane
и JPanel
расширяют JComponent
и реализуют Accessible
. Однако JComponent
не реализует Accessible
. Результатом является наиболее полный, специфический тип, который компилятор может получить вместе со всеми типами. Для вашего первого примера выведенный тип List<Class<? extends JComponent & Accessible>>
, потому что оба аргумента соответствуют этому типу. Когда вы добавляете JComponent
, выводимый тип теперь List<Class<? extends JComponent>>
и соответствует listComp
, позволяя ему компилироваться в Java 7.
Java 8 улучшает вывод целевого типа. Этот пример учебника относится к Collections.emptyList
, который передается методу, требующему List<String>
. В Java 7 предполагаемый тип будет List<Object>
и произойдет ошибка компиляции. Однако в Java 8, выводимый тип List<String>
, сопоставление параметра метода и компиляции кода.
Это не совсем тот же пример, что и ваш код, но он достаточно близок, и я считаю, что в целом Java 8 улучшает вывод целевого типа, объясняет, почему код компилируется с этой версией.