62
public void increment(){
    int zero = 0;

    int oneA = zero++; // Compiles

    int oneB = 0++; // Doesn't compile

    int oneC = getInt()++; // Doesn't compile
}

private int getInt(){
    return 0;
}

都是int的,为什么B&C编译不出来?是否与++operator 不同的方式有关= 0 + 1;

操作参数无效 ++/--

4

11 回答 11

149

i++是对变量的赋值i

在您的情况下,zero++等效于zero = zero + 1. 所以0++意味着0 = 0 + 1,这没有任何意义,以及getInt() = getInt() + 1

更精确地 :

int oneA = zero++;

方法

int oneA = zero;
zero = zero + 1; // OK, oneA == 0, zero == 1

int oneB = 0++;

方法

int oneB = 0;
0 = 0 + 1; // wrong, can't assign value to a value.

int oneC = getInt()++;

方法

int oneC = getInt();
getInt() = getInt() + 1; // wrong, can't assign value to a method return value.

从更一般的角度来看,变量是L-value,这意味着它指的是内存位置,因此可以被分配。L in L -value 代表赋值运算符的左侧(即=),即使 L 值可以在赋值运算符的左侧或右侧找到(x = y例如)。

相反的是R 值R代表赋值运算符的右侧)。R-values 只能用在赋值语句的右侧,将某些东西赋给 L-value。通常,R 值是文字(数字、字符串...)和方法。

于 2013-03-08T10:32:43.477 回答
29

因为如 JLS所述:

后缀表达式的结果必须是可转换(第 5.1.8 节)为数字类型的类型的变量,否则会发生编译时错误。

于 2013-03-08T10:32:12.093 回答
14

getInt()不是int

getInt()返回int

++操作员做了两件事increment+assignment

因此,++要让操作员工作,您需要一个变量来存储增量操作的结果,0getInt()两者都不是。

于 2013-03-08T10:32:36.907 回答
10

前置和后置运算符仅在调用它们时对变量或左值进行操作。lvalue 是左值的缩写,即在赋值中可以站在左边的东西。在您的示例中:

    zero = 1; // OK
    0 = 1; // Meaningless
    getInt() = 1; // Also meaningless

//jk

于 2013-03-08T10:35:20.950 回答
5

B 和 C 都使编译器说:

意外类型,必需:变量,找到:值

所以你不能增加一个值,只能增加一个变量。

于 2013-03-08T10:32:11.540 回答
4

为什么后自增运算符不适用于返回 int 的方法?

因为它是一个getter方法,通过getter改变一个值是没有意义的。


int z = x + y++;

相当于:

int z = x + y;
y = y + 1;

所以有类似的东西是无效的:

int z = x + getY()++;

这相当于:

int z = x + getY();
getY() = getY() + 1; // invalid!
于 2013-03-08T10:34:21.110 回答
3

0++

它等同于0 = 0 + 1;并且当然不可能。

即它必须l-value分配给它。

getInt()++;

类似的原因在这里。

于 2013-03-08T10:34:45.380 回答
2

因为0是一个rValue(即您只能从赋值运算符的右侧使用它)not a lValue

++运算符增加值并将其设置为自身,因此0++会给您一个错误。

于 2013-03-08T10:32:44.293 回答
1

我的回答有点“开箱即用”。

当我对运算符的用法有疑问时,我认为该运算符的“其重载函数等效”?

我知道,Java 运算符没有运算符重载,它只是一种解决方案的替代方法。

在这种情况下:

...
x++;
...

应该读作:

...

int /* function */ postincrement (/* ref */ int avalue)
{
  int Result = avalue;

  // reference value, 
  avalue = avalue + 1;

  return Result;
}

...
postincrement(/* ref */ x);
...

和:

...
++x;
...

...

int /* function */ preincrement (/* ref */ int avalue)
{
  // reference value, 
  avalue = avalue + 1;

  int Result = avalue;

  return Result;
}

...
preincrement(/* ref */ x);
...

因此,“++”的两个版本都作为一个通过引用接收可变参数的函数工作。

因此,像“0++”这样的字面值或像“getInt()++”这样的函数结果,都不是变量引用。

干杯。

于 2013-03-15T18:11:31.540 回答
0

由于函数返回是 RHS 表达式,并且前/后递增/递减操作只能应用于 LHS 表达式。

于 2013-03-19T11:53:51.487 回答
0

postincrement 和 preincrement 只能在变量的帮助下应用。所以第一种情况编译。

于 2013-03-13T06:33:05.130 回答