2009-09-18 1 views

ответ

22

Пробуя простую программу (используя как 0, так и 100, чтобы показать разницу между «специальными» константами и общими), компилятор Sun Java 6 выдаст тот же байт-код для 1 и 2 (случаи 3 и 4 идентичен 2 в отношении компилятора).

Так, например:

double x = 100; 
double y = 100.0; 

компилирует:

0: ldc2_w #2; //double 100.0d 
3: dstore_1 
4: ldc2_w #2; //double 100.0d 
7: dstore_3 

Однако, я не вижу ничего в Java Language Specification гарантирующий это время компиляции расширение постоянных выражений. Там же во время компиляции сужение для случаев, как:

byte b = 100; 

, как указано в section 5.2, но это не совсем то же самое.

Может быть, кто-то с более острыми глазами, чем я могу найти гарантию где-то там ...

+0

Не могли бы вы предложить хороший ресурс, где можно прочитать о том, что означает ldc2_w и другие инструкции? –

+2

Спецификация JVM: http://java.sun.com/docs/books/jvms/ –

2

Последние 3 должны быть идентичными. Литерал с правой стороны уже двойной. «D» или «D» подразумевается, когда у вас есть десятичный литерал.

Первый из них несколько отличается тем, что 0 - это int literal, который будет расширен до двойника. Я не знаю, создает ли в этом случае другой байт-код или нет; результат должен быть идентичным в любом случае.

+0

Спасибо за ответ, я знаю, что результаты идентичны, я хочу знать различия под капотом. –

+0

Для «0.0», «0.0d» и «0.0D» на капоте нет никаких различий. Это три способа написания двойного литерала, все они в точности эквивалентны. – Jesper

-2

для Java Я точно не знаю, на C это может быть действительно опасно, если вы опустите этот D в конце, так как он не изменит верхние байты, что может иметь эффект, который в вашей переменной лежит в номере, который вы на самом деле не сделали Путин!

В Java у меня была действительно большая проблема с установкой BigDecimal - новый BigDecimal (0) и новый bigDecimal (0L) - это не то же самое, вы можете почувствовать это, если перенести свой код с Java 1.4 на Java 1.5. Не знаю, почему они были небрежны в этом, может быть, они должны были это сделать.

+1

Ваш ответ не отвечает на вопрос. Что происходит в C, не имеет значения, и это не то, что ваш опыт работы с BigDecimals. –

13

Для первого:

double dummy = 0; 

целочисленного литерал 0 преобразуется в двойной с увеличивающимся примитивным преобразованием , см. 5.1.2 Widening Primitive Conversion в спецификации языка Java. Обратите внимание, что это делается полностью компилятором, это не влияет на созданный байт-код.

Для остальных:

double dummy = 0.0; 
double dummy = 0.0d; 
double dummy = 0.0D; 

Эти три точно такие же - 0.0, 0.0d и 0.0D лишь три различных способа написания double буквальным. См. 3.10.2 Floating-Point Literals в JLS.