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

Различие между Java 5 и 6 при перегрузке общих методов

Я столкнулся с проблемой в Java Generics, в которой тот же код будет компилироваться и отлично работать в Java 6, но не сможет скомпилироваться из-за того же стирания в Java 5. У меня есть файл TestErasure.java, который имеет перегруженный метод, называемый "метод":

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

public class TestErasure {
 public static Object method(List<Object> list) {
     System.out.println("method(List<Object> list)");
     return null;
 }

 public static String method(List<String> list) {
     System.out.println("method(List<String> list)");
     return null;
 }

 public static void main(String[] args) {
     method(new ArrayList<Object>()); 
     method(new ArrayList<String>()); 
 }
}

В Java 5 я получаю ожидаемую ошибку компиляции, заявляя, что стирание "метода" одинаково:

$ javac -version
javac 1.5.0_19
$ javac TestErasure.java
TestErasure.java:10: name clash: method(java.util.List<java.lang.String>) and method(java.util.List<java.lang.Object>) have the same erasure
        public static String method(List<String> list) {
                             ^
TestErasure.java:17: method(java.util.List<java.lang.Object>) in TestErasure cannot be applied to (java.util.ArrayList<java.lang.String>)
      method(new ArrayList<String>()); 
            ^
2 errors

Однако Java 6 может компилировать и запускать этот же код.

$ javac -version
javac 1.6.0_16
$ javac TestErasure.java
$ java TestErasure
method(List<Object> list)
method(List<String> list)

Основываясь на моем нынешнем понимании стираний (благодаря Jon Skeet и Angelika Langer), я на самом деле ожидал ошибку компиляции, которая была выбрана Java 5 (если только что-то не изменилось в том, как Java обрабатывал Generics, чего я не могу найти в заметках о выпуске Java 6). Фактически, если я изменяю тип возвращаемого значения одного из перегруженных методов:

public static Object method(List<Object> list) ...
public static Object method(List<String> list) ...

Java 6 также не может скомпилироваться из-за одинаковых стираний:

$ javac TestErasure.java TestErasure.java:5: name clash: method(java.util.List<java.lang.Object>) and method(java.util.List<java.lang.String>) have the same erasure
     public static Object method(List<Object> list) {
                          ^
TestErasure.java:10: name clash: method(java.util.List<java.lang.String>) and method(java.util.List<java.lang.Object>) have the same erasure
     public static Object method(List<String> list) {
                          ^
2 errors

Кажется, что возвращаемый тип в Java 6 каким-то образом влияет на выбор того, какой перегруженный метод использовать?

Может ли кто-то пролить свет на то, почему первый пример работает на Java 6 - похоже, это противоречит заявленной обработке перегруженных общих методов?

Дополнительная информация:

По предложению Дэвида исходный пример, выполняемый javac 1.6, будет работать под java 1.5:

$ javac -target 1.5 TestErasure.java
$ java -version
java version "1.5.0_19"
$ java TestErasure 
method(List<Object> list)
method(List<String> list)
4b9b3361