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

Почему автоматический бокс работает в eclipse, но не в javac?

Этот код:

Integer ints[] = new Integer[]{'1', '2', '3'};

просто компилируется в eclipse, но javac (обе версии 1.6.0_27 и 1.7.0) дает следующую ошибку:

BoxTest.java:4: incompatible types
found   : char
required: java.lang.Integer
               Integer ints[] = new Integer[]{'1', '2', '3'};

BoxTest.java:4: incompatible types

Почему?

Я предполагаю, что это какой-то флаг компилятора, но выкапывать затмение затмения, чтобы понять его, не совсем прямо.

4b9b3361

Ответ 1

Что javac не делает, это не автобоксинг, а автоматический литье. В javac он компилируется с помощью:

Integer ints[] = new Integer[] { (int) '1', (int) '2', (int) '3' };

То же самое происходит только с одним Integer, снова в javac, я должен выполнить явное преобразование для компиляции:

Integer a = (int) '1';

Но вот что я нашел. Используя пакетный компилятор Eclipse JDT из командной строки, в котором он работает, даже без приведения:

$ java -jar org.eclipse.jdt.core_3.7.1.v_B76_R37x.jar -classpath rt.jar \
  -1.6 Appo.java 

Я просмотрел параметры javac, и я не думаю, что есть способ изменить это поведение.

Я должен сделать вывод, что разница вызвана тем, что Eclipse не использует javac внутренне, а компилятор JDT.

Ответ 2

Как уже отмечалось stivlo, компилятор Eclipse JDT молча обрабатывает такой код:

Integer refI = Integer.valueOf((int)'a');

Но спецификация языка Java говорит в глава 5.2 (внимание мое):

Преобразование присваивания происходит, когда значение выражения присвоен (§15.26) переменной: тип выражения должен быть преобразуется в тип переменной. Контексты присваивания позволяют использование один из следующего:

* an identity conversion (§5.1.1)
* a widening primitive conversion (§5.1.2)
* a widening reference conversion (§5.1.5)
* a boxing conversion (§5.1.7) optionally followed by a widening reference conversion
* an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.

Листинг (int) 'a' - это первое преобразование, а Integer.valueOf(int) - второе преобразование. Компилятор javac обеспечивает соблюдение правил, разрешая только одно преобразование.

Итак, вы обнаружили ошибку в компиляторе Eclipse JDT.

Ответ 3

Я нашел много путаницы в этом потоке о том, как Eclipse компилирует Java-код. Здесь сделка - Eclipse использует свой собственный JDT-компилятор, который не имеет ничего общего с компилятором Java или Sun (теперь Oracle). Это самостоятельно разработанный компилятор, лицензированный под EPL, и следует за JLS, так же, как это делает javac. Так что независимо от того, что/не компилируется с javac, делает/не компилируется с Eclipse JDT.

Тем не менее, проблема, о которой идет речь, выглядит как ошибка в компиляторе Eclipse. https://bugs.eclipse.org/bugs/show_bug.cgi?id=362279

Ответ 4

Окно → Предпочтение → Компилятор → Ошибки/Предупреждение → Потенциальные проблемы программирования - > Бокс и распаковка конверсий; установите значение Ошибка

Ответ 5

Возможно, флаг -source установлен в пред-боксерскую версию Java? например

javac -source 1.4 BoxTest.java

Ответ 6

Собственно, в Eclipse IDE используется Java @SuppressWarnings:

http://knol.google.com/k/suppresswarnings-annotation-in-java#

Моральный эквивалент javac - это XList: xxx options:

http://download.oracle.com/javase/1,5.0/docs/tooldocs/windows/javac.html#options

ДОПОЛНЕНИЕ:

  • Eclipse использует стандартный JDK, частью которого является javac.

  • Часть различий может быть учтена внутренним использованием Eclipse (что другие языки иногда называют "прагмами" ), например, @sSuppressWarnings.

  • Главное отличие состоит в том, что Eclipse использует библиотеки JDT, которые находятся под исполняемым файлом javac.

  • Здесь отличная дискуссия:

'Надеюсь, что это поможет.. PSM