Вопрос о ** механизме стирания типа ** при прочтении Core Java 11th ed - PullRequest
0 голосов
/ 09 марта 2020

Это пример кода Generi c Программирование, которое автор предоставляет в книге:

public class Pair<T>
{
  private T first;
  private T second;
  public Pair() { first = null; second = null; }
  public Pair(T first, T second) { this.first = first; this.second = second; }
  public T getFirst() { return first; }
  public T getSecond() { return second; }
  public void setFirst(T newValue) { first = newValue; }public void setSecond(T newValue) { 
  second = newValue; }
}

, затем автор вводит механизм стирания типов

Всякий раз, когда вы определяете универсальный тип c, соответствующий необработанный тип предоставляется автоматически. Имя необработанного типа - это просто имя обобщенного типа c с удаленными параметрами типа. Переменные типа стираются и заменяются их ограничивающими типами (или, например, необработанным типом для Object для переменных без границ).

Ваши программы могут содержать различные виды стирания, превращающие их все в необработанную пару, такую ​​как Pair<String> или Pair<LocalDate>, но стирание превращает их всех в необработанные типы пар.

Так что для случая class Pair<T> , после стирания он становится необработанным типом пары ниже:

public class Pair
{
  private Object first;private Object second;
  public Pair(Object first, Object second)
  {
  this.first = first;
  this.second = second;
  }
  public Object getFirst() { return first; }
  public Object getSecond() { return second; }
  public void setFirst(Object newValue) { first = newValue; }
  public void setSecond(Object newValue) { second = newValue; }
}

, поэтому, если мы запустим удар по коду, напечатает TURE

Pair<Integer> p = new Pair<Integer>(1, 2);
Pair<String> s = new Pair<String>("a", "b");
System.out.println(p.getClass()==s.getClass());

Здесь возникает вопрос , когда я создаю экземпляр Pair<T> с неправильным типом, таким как:

 Pair<String> s = new Pair<String>("a", 1);

Компилятор может выяснить проблему и напечатать это сообщение:

pair1 / PairTest1. java: 12: ошибка: несовместимо типы: int нельзя преобразовать в строковую пару s = новая пара ("a", 1);

, так как <T> стирается в объект, и конструктор становится:

public Pair(Object first, Object second)
  {
  this.first = first;
  this.second = second;
  }

и тип параметра становится Object, поэтому:

Как происходит компиляция Выяснили ли вы, что тип неправильный? или Когда происходит стирание типа ?

1 Ответ

1 голос
/ 09 марта 2020

Стирание типа происходит, когда компилятор генерирует байт-код, но компилятору известны типы generic c, когда он проверяет исходный код. На этом этапе еще ничего не было стерто.

Однако компилятор знает, что удаление произойдет даже во время проверки. Например, если вы перегружаете метод, подобный этому:

void doStuff(List<Integer> intList) {}
void doStuff(List<String> stringList) {}

, компилятор знает, что оба будут void doStuff(List xxx) {} после стирания, и у вас не может быть двух методов с одинаковой сигнатурой 1 таким образом, шаг проверки выдаст сообщение об ошибке, даже если стирание типа еще не произошло.

1) Имя параметра не является частью подписи

...