Я создал MWE, где смена одной строки путем добавления <?>
решает ошибку компилятора.Опуская <?> unintuitly нарушает этот код
Следующий код не компилируется:
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
решает эту проблему. Интересно, почему тип возврата для for-each рассматривается как Object
, а не как String
, если я не добавлю шаблон к родительскому классу? Обратите внимание, что getLabels()
сам по себе не содержит дженериков.
Согласно Chapter 14.14.2. of the Java Language Specification, каждый из них скомпилирован в цикл с использованием итератора. Интересно отметить, что расширение для-каждого такому итератора вручную работы:
Iterator<String> iterator = myEntity.getLabels().iterator();
while (iterator.hasNext()) {
String label = iterator.next();
/* ... */
}
Может кто-нибудь объяснить, почему?
Ницца один, никогда не видел, что раньше – Andremoniy