Странное поведение с параметризованным методом для абстрактного класса

Кто-то может сказать мой, почему это дает ошибку компиляции? Я не вижу почему бросок к во вторых строках причин для цикла () для возврата общего Списка Объектов.

import java.util.ArrayList;
import java.util.List;

public class E {

    public static void main(String[] args) {
        for (String s : new D().strings()) {
            System.out.println("s = " + s);
        }
        for (String s : ((A) new D()).strings()) {
            System.out.println("s = " + s);
        }
    }

    static class D extends A<C> {
    }

    static abstract class A<T extends B> {
        List<String> strings() {
            return new ArrayList<String>() {{
                add("Foo");
                add("Bar!");
            }};
        }
    }

    static class B {
    }

    static class C extends B {
    }
}

Действительно ли это - причуда Дженериков?

Спасибо, Kristian

5
задан skaffman 9 June 2010 в 21:00
поделиться

1 ответ

В строке:

    for (String s : ((A) new D()).strings()) {

Вы приводите к типу raw A, поэтому там вы теряете информацию об аргументах типа. В Java любой метод использования или поле типа raw также приведет к типу raw (даже если вся параметризованная информация доступна) -- хорошо сырой тип или непараметризованный технически. Поэтому A.string() рассматривается как тип raw List, а не как List.

Как указывает JSL в Разделе 4.8:

Тип конструктора (§8. 8), метод экземпляра (§8.8, §9.4), или нестатическое поле (§8.3) M необработанного типа C, которое не наследуется от его суперклассов или супер-интерфейсов, является стиранием его типа в общей декларации, соответствующей C. Тип статического члена необработанного типа С совпадает с его типом в общем объявлении, соответствующем C.

7
ответ дан 14 December 2019 в 08:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: