有谁能告诉我为什么我在这里遇到编译错误?
class NewInteger{
public static void main(String[] args){
Integer i = new Integer(200);
Integer j = ++i; //ok
Integer k = ++(new Integer(300)); //compile error: unexpected type
// required: variable
// found: value
}
}
对我而言,违规行仅仅是前面两行中的一个版本。
答案 0 :(得分:8)
++
从变量读取,增加读取的值,写回到变量。 new Integer(300)
不是变量,你不能写它。
这是两个示例之间的重要区别:在j = ++i
案例中,++
有一些可以回写的内容(i
)。在第二种情况下,它没有。
(在这里使用“变量”JLS经常[虽然奇怪地不总是]这样做,表示局部变量和实例或类字段。)
答案 1 :(得分:2)
对我而言,违规行仅仅是前面两行中的一个版本。
事实并非如此。 ++
(两者,其前缀及其后缀版本)对其操作数有副作用,这要求操作数是变量而不仅仅是某个表达式。忽略前缀/后缀区别,
Integer j = ++i;
实际上就像是
Integer j = (i += 1); // Note the side-effect on i
精神上。
要查看副作用,请尝试在第二行之前打印i
的值,即
System.out.println(i);
Integer j = ++i;
System.out.println(i);
并观察,打印的值不同。
答案 2 :(得分:1)
在从C派生的语言(如Java)中,有两种类型的表达式:左值和右值。左值是可以出现在赋值表达式两侧的值,右值只出现在右侧。通常左值是变量的名称,这意味着它们在内存中具有特定的位置来支持它们。这是有道理的,因为当你执行赋值时,左边的表达式需要有一个存储结果的位置。例如,表达式a
是变量的名称,因此它可以是左值。但是a + 1
只计算一个临时结果,因此如果它被用作赋值位置,则无处存储该值。
++
运算符需要左值,因为除了向表达式添加一个值,它还会尝试将结果存储在递增的变量中。在第一个例子中,这是有效的,因为i
是一个左值,它可以将计算结果存储在变量的内存中。在第二个示例中,(new Integer(300))
是一个右值,因为它只是一个临时计算,没有存储结果的位置。因此,它不能与++
运算符一起使用。
答案 3 :(得分:0)
你只能增加变量。 在第一个案件
Integer j = ++i;
您已增加一个varibale并分配给整数类型j。
在第二种情况下,你想增加一个不可能的类Integer
Integer k = ++(new Integer(300));