Двойная инициализация Java - PullRequest
27 голосов
/ 18 сентября 2009

Чем эти утверждения отличаются?

  1. двойной манекен = 0;
  2. двойной манекен = 0,0;
  3. двойной манекен = 0,0d;
  4. двойной манекен = 0,0D;

Ответы [ 4 ]

23 голосов
/ 18 сентября 2009

Попробовав простую программу (используя 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 , гарантирующей это расширение константных выражений во время компиляции. Время компиляции сужается для таких случаев, как:

byte b = 100;

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

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

14 голосов
/ 18 сентября 2009

Для первого:

double dummy = 0;

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

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

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

Эти три абсолютно одинаковы - 0.0, 0.0d и 0.0D - это всего лишь три разных способа написания литерала double. См. 3.10.2 Литералы с плавающей точкой в JLS.

3 голосов
/ 18 сентября 2009

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

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

0 голосов
/ 18 сентября 2009

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

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

...