Я создал MWE, где изменение одной строки путем добавления <?>
решает ошибку компилятора.
Следующий код не компилируется:
import java.util.List;
public class MainClass {
public void traverse() {
List<MyEntity> list = null /* ... */;
for (MyEntity myEntity : list) {
for (String label : myEntity.getLabels()) { // <-- Offending Line
/* ... */
}
}
}
interface MyEntity<T> {
T get();
List<String> getLabels();
}
}
Ошибка компилятора:
Error:(9, 51) java: incompatible types: java.lang.Object cannot be converted to java.lang.String
Изменение определения в строке нарушения от MyEntity myEntity
до MyEntity<?> myEntity
решает проблему. Интересно, почему тип возврата для каждого из них рассматривается как Object
, а не как String
, если я не добавлю шаблон к родительскому классу? Обратите внимание, что getLabels()
сам по себе не содержит дженериков.
Согласно Глава 14.14.2. спецификации языка Java, каждый из них скомпилирован в цикл с использованием итератора. Интересно, что расширение каждого из них для такого итератора вручную работает:
Iterator<String> iterator = myEntity.getLabels().iterator();
while (iterator.hasNext()) {
String label = iterator.next();
/* ... */
}
Может кто-нибудь объяснить, почему?