Недавно я наткнулся на фрагмент кода, который не компилировался в моем Eclipse из-за проблемы с "одним и тем же стиранием" (выглядел очень похоже на этот). Ребята, написавшие код, заверили меня, что он компилируется в их локальной среде и их непрерывной интеграции, поэтому я подыгрывал, чтобы сымитировать его.
Взгляните на этот фрагмент:
package com.mycompany.playground;
import java.util.ArrayList;
import java.util.Collection;
public class GenericsTest {
public static void main (String[] args) {
System.out.println(GenericsTest.doSomething(new ArrayList<A>()));
System.out.println(0 == GenericsTest.doSomething(new ArrayList<C>()));
}
public GenericsTest() {
}
public static String doSomething(Collection<A> listOfA) {
return "has done something to Collection<A>";
}
public static Integer doSomething(Collection<C> listOfC) {
return 0;
}
private class A {
}
private class C {
}
}
Eclipse Helios с 1.6.0_21 JDK в качестве рабочего пространства по умолчанию не будет компилировать его и будет жаловаться, что метод doSomething(Collection) имеет то же стирание doSomething(Collection), что и другой метод типа GenericsTest. То же самое можно сказать и о другом методе.
Пробовал принудительно запускать Eclipse и увидел: Исключение в потоке "main" java.lang.Error: Нерешенная проблема компиляции: Метод doSomething(Collection) в типе GenericsTest неприменим для аргументов (ArrayList).
В порядке. Этого следовало ожидать. В настоящее время. Если я войду в свою командную строку и запущу просто:
javac GenericsTest.java
он компилируется. Я проверил 1.6.0_21 и 1.6.0_06 (тот, что у парней был в их окружении) и ни один из них не жаловался. Я скопировал файлы классов туда, где их ожидал Eclipse, и заставил его запустить его снова.
Он печатает:
has done something to Collection<A>
true
Если я заменю
System.out.println(0 == GenericsTest.doSomething(new ArrayList<C>()));
с участием
System.out.println(GenericsTest.doSomething(new ArrayList<C>()));
он по-прежнему будет компилироваться без предупреждений из командной строки, но при попытке запустить его будет выдавать ту же «Нерешенную проблему компиляции».
Здесь два вопроса.
Неужели javac просто перехитрил встроенный компилятор Eclipse? Выглядит почти так же, как этот ранее заданный вопрос поэтому я верю, что знаю ответ. (кстати, как я могу заставить Eclipse использовать javac вместо этого?).
Зачем javac молча компилировать то, что java затем не запустится (второй сценарий с удаленной "подсказкой" {0 ==}?
javac
неправильный. Спецификация языка Java говорит об этом. В частности, Раздел 8.1.2 Общие классы и типы Параметры охватывают общий тип и 8.4.2 Сигнатура метода описывает, какие сигнатуры вызовут ошибки времени компиляции. - person Powerlord   schedule 05.11.2010