Подтвердить что ты не робот

Почему необработанные типы в одном месте заставляют родовые призывы в другом месте рассматриваться как сырые?

Рассмотрим следующий пример:

import java.util.*;

class Foo<T> {
  public int baz(List<String> stringlist) { return 1; }
  public int baz(ArrayList<Object> objectlist) { return 2; }

  public static void main(String[] args) {
    Foo<String> foo = new Foo<String>(); // (A)
    //Foo foo = new Foo();               // (B)

    System.out.println(foo.baz(new ArrayList<String>()));
  }
}

Почему он печатает 1 в (A), но 2 с (B)?

Я знаю, как работает разрешение метода, поэтому мне не нужно объяснять это мне.

Я хочу узнать более глубокую мотивацию этой "функции". Почему в этом нет предупреждения о стирании? (Существует только один о Foo foo = new Foo().)

Почему разрешение метода использует стираемую семантику, хотя задан общий тип?

4b9b3361

Ответ 1

Это потому, что, когда компилятор разрешает перегрузки, он рассматривает каждый метод как общий или не общий, ни один из двух, поэтому кандидаты:

  • Foo<T>.baz(List<String>)
  • Foo<T>.baz(ArrayList<Object>)

если foo является Foo<String>, или

  • Foo.baz(List)
  • Foo.baz(ArrayList)

если foo является foo.

Нет такой вещи, как Foo.baz(List<String>). Рассматриваются либо все параметры типа, либо нет. (Я не знаю, что это явно указано в JLS, но имеет смысл с тех пор, как обрабатывать общий метод, как если бы это был исходный эквивалент, это функция обратной совместимости.)

В первом случае Foo<T>.baz(List<String>) соответствует, но Foo<T>.baz(ArrayList<Object>) не работает.

Во втором случае обе функции соответствуют, а Foo.baz(ArrayList) - более конкретный, поэтому он выбран.

Ответ 2

Он даже не будет компилировать регистр (A), если вы сохраняете только один метод baz(ArrayList<Object>) (метод error: нельзя применить к заданному типу). Я думаю, ArrayList<String> не является подклассом ArrayList<Object>.

Странно, что он компилируется в случае (B), но они, должно быть, приняли некоторые странные решения, чтобы сохранить обратную совместимость с коллекциями с не общим набором.