У меня возникла странная ошибка компилятора при использовании дженериков в цикле for-each в Java. Это ошибка компилятора Java или мне что-то здесь действительно не хватает?
Вот весь мой класс:
public class Generics<T extends Object> {
public Generics(T myObject){
// I didn't really need myObject
}
public List<String> getList(){
List<String> list = new ArrayList<String>();
list.add("w00t StackOverflow");
return list;
}
public static void main(String...a){
Generics generics = new Generics(new Object());
for(String s : generics.getList()){
System.out.println(s);
}
}
}
Компилятор жалуется на строку с for-each: «Несоответствие типов не может преобразовать из типа элемента Object в String».
Если я сделаю это тонкое изменение, он скомпилирует:
public static void main(String...a){
Generics<?> generics = new Generics(new Object());
for(String s : generics.getList()){
System.out.println(s);
}
}
Я знаю, что getList()
действительно использует дженерики, но он использует их, как я думал, совершенно не связанным образом. Я мог бы понять это, если бы пытался перебрать что-то типа T, а getList()
вернул List<T>
или что-то в этом роде, но здесь это не так. Тип возвращаемого значения getList()
не должен иметь ничего общего с T и не должен заботиться о том, использую ли я необработанный тип для своего объекта Generics или нет ... верно? Разве они не должны быть совершенно не связаны друг с другом, или я действительно чего-то здесь упускаю?
Обратите внимание, что код также компилируется, если я это сделаю, что, как я думал, тоже должно было быть эквивалентно первому:
public static void main(String...a){
Generics generics = new Generics(new Object());
List<String> list = generics.getList();
for(String s : list){
System.out.println(s);
}
}
<T extends Object>
ничем не отличается от<T>
. Вы не создаете общую версию своего класса, вы создаете необработанный тип. Это подводит нас к вопросу, почему ваш класс вообще является универсальным? Единственное место, где вы используете T, - это конструктор, и вы не используете эту ссылку. - person unholysampler   schedule 25.03.2011<T extends Object>
, потому что мне просто нужно было что-то для примера. Настоящий код, очевидно, является чем-то другим, и он действительно использует T ... он просто использует T способом, совершенно не связанным сgetList()
. - person Michael McGowan   schedule 25.03.2011<T extends *something*>
, не акцентируя внимание на том, что это было за что-то, поэтому я выбралObject
для своего примера. - person Michael McGowan   schedule 25.03.2011