Я столкнулся с проблемой в Generics Java, в которой тот же код будет компилироваться и нормально работать в Java 6, но не удастся компилировать из-за того же стирания в Java 5. У меня есть файл TestErasure.java, который имеет перегруженный метод с именем «method»:
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)