可以对任何原始类型使用增量运算符吗?

Is it ok to use increment operators with any primitive type?

我们都知道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 吗?

++(前缀或后缀)不是只适用于 int 的东西,如果您将它与其他原始类型一起使用,这并不意味着存在到 [ 的中间转换=12=] 然后返回。

请参阅 Java 语言规范:

正如 JLS 所说,binary numeric promotion 应用于变量和值 1。在 number++ 的情况下,其中 numberdouble,这意味着 1 被视为 double

因此,如果 numberdoublenumber++number += 1D 的工作原理相同。没有必要明确地number += 1D

注意:如果中间转换为 int 并返回,如您在问题中所建议的那样,那么您会期望:

double number = 0.5;
number++;

会导致 number 变成 1.0 而不是 1.5,因为转换会丢掉小数点。但是,如您所见,情况并非如此。

别担心。编译器知道如何最好地递增 int、float 或 double 类型。它将为每种情况生成高效的代码。如果您查看生成的汇编代码,它很可能是为以下内容生成的相同代码:

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

但请注意,对于 class 类型,事情要复杂得多。在那里,使用了 operator+ 或 operator+= 重载。通常,post-增量操作更耗时,因为必须在增量之前保存对象状态。因此,您应该习惯于始终使用预增量版本,即使对于标量类型也是如此——除非您确实需要 post-增量操作。

代码

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