2015-06-26 3 views
-3

Мы все знаем, что int++ увеличит значение переменной на 1, то есть:Можно ли использовать операторы инкремента с любым примитивным типом?

int number = 0; 
int temp = number + 1; 
number = temp; 

Это разрешено другими примитивными типами тоже:

double number = 0D; 
number++; 

Итак, мне было интересно, если приведенный выше код будет выполняться как:

double number = 0D; 
double temp = number + 1D; 
number = temp; 

Или:

double number = 0D; 
int temp = number + 1; 
number = temp; 

Во втором случае мы должны предпочесть double += 1D?

+5

Пытались ли вы, что происходит? – Kayaman

+0

@ Кайаман. Любой примитивный тип увеличивается на 1. –

+3

Ну, вот ваш ответ. – Kayaman

ответ

4

++ (префикс или постфикс) не то, что просто работает на int и если вы используете его с другими примитивными типами, это вовсе не означает, что существует промежуточное преобразование в int и обратно.

Смотрите спецификацию Java Язык:

Как говорит JLS, binary numeric promotion применяется к переменной и значение 1. В случае number++, где number является double, это означает, что 1 рассматривается как double.

Таким образом, number++ работает так же, как number += 1D, если number является double. Нет необходимости делать number += 1D явно.

Примечание: Если бы промежуточное преобразование в int и обратно, как вы предлагаете в вашем вопросе, то можно было бы ожидать, что:

double number = 0.5; 
number++; 

приведет к number быть 1.0 вместо 1.5, потому что преобразование отбрасывало бы десятины. Но, как видите, это не так.

1

Не беспокойтесь. Компилятор знает, как лучше всего увеличивать int, float или double типы. Он будет генерировать эффективный код для каждого случая. Если посмотреть на сгенерированный код на ассемблере будет больше всего нравится быть такой же код, генерируемый для:

doubleVar++; 
++doubleVar; 
doubleVar += 1; 
doubleVar += 1.0; 

Но следует помнить, что для типов классов все гораздо сложнее. Там используется оператор + или оператор + = перегрузки. Как правило, операции после инкремента более трудоемки, так как состояние объектов должно быть сохранено до приращения. Поэтому вы должны привыкнуть всегда использовать версию предварительного инкремента, даже для скалярных типов, за исключением того, что вам действительно нужна операция после инкремента.

1

Код

double number = 0D; 
number++; 

выполнен в виде

double number = 0D; 
number = number + 1D; 

генерируемого байткод

// double number = 0D; 
0: dconst_0 
1: dstore_1 

// number + 1D 
2: dload_1 
3: dconst_1 
4: dadd 

// number = 
5: dstore_1