Пример стирания типа и моего понимания
private void readList(ArrayList list){
list.add("Hello");
list.add(2);
}
public void run(){
setFont("Courier-24");
ArrayList<Integer> list = new ArrayList<Integer>();
readList(list);
println("list = "+list);
println("Type of list[1] = "+list.get(1).getClass());
}
Результат:
list = [Привет, 2]
Тип списка [1]= класс java.lang.Integer
public void run(){
setFont("Courier-24");
ArrayList<Integer> list = new ArrayList<Integer>();
readList(list);
println("list = "+list);
println("Type of list[0] = "+list.get(0).getClass());
}
Результат:
list = [Привет, 2]
Исключение в потоке "Thread-2" java.lang.ClassCastException:
Строка не может быть приведена к java.lang.Integer
Прочитав что-то о type erasure
У меня есть предположение:
Когда я звоню readList(list)
, это на самом деле добавление вещей в список, который "ложно" рассматривается как тип ArrayList
так что ошибки нет (это мое понимание так называемого type erasure
). Но если я позвоню println("Type of list = "+list.get(0).getClass());
в run()
появляется ошибка, потому что list[0]
имеет тип String
(в то время как println("Type of list = "+list.get(1).getClass());
не потому, что список [1] имеет тип Integer
).
Как будто какой-то преступник сбежал с места преступления сначала (потому что он принадлежит нормальным людям, а у нормальных людей есть свобода), а позже, когда полиция начинает проверять всех, кто был рядом, его поймали, потому что он глубоко преступник?
2 ответа
Когда ты сказал
private void readList(ArrayList list){
это не стирание типа. Это пример raw type
, В соответствии с учебниками Java,
Необработанный тип - это имя универсального класса или интерфейса без аргументов типа.
до добавления дженериков в Java существовали только необработанные типы.
В типе Estrast стирание является оптимизацией. Обобщенные данные - это функция проверки типов во время компиляции, которая не оказывает влияния на производительность, поскольку универсальные типы не проверяются во время выполнения.
1 В байт-код вставлено приведение типа.
Идти вместе type erasure
принципы ваш метод должен выглядеть
private void readList(ArrayList<Integer> list){
list.add(1);
list.add(2);
}
Очевидно, что добавление строки в массив целых чисел не является хорошей идеей.