Почему автоматический бокс работает в 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
Почему?
Я предполагаю, что это какой-то флаг компилятора, но выкапывать затмение затмения, чтобы понять его, не совсем прямо.
Ответы
Ответ 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