在方法或类范围中,下面的行编译(带警告):
int x = x = 1;
在类范围中,变量获取默认值,以下内容给出了“未定义引用”错误:
int x = x + 1;
是不是第一个x = x = 1
最终会出现相同的“未定义引用”错误?或者第二行int x = x + 1
应该编译?或者有一些我想念的东西?
答案 0 :(得分:86)
int x = x = 1;
相当于
int x = 1;
x = x; //warning here
在
中int x = x + 1;
首先我们需要计算x+1
但是x的值是未知的,所以你得到一个错误(编译器知道x的值是未知的)
答案 1 :(得分:41)
大致相当于:
int x;
x = 1;
x = 1;
首先,int <var> = <expression>;
始终等同于
int <var>;
<var> = <expression>;
在这种情况下,您的表达式为x = 1
,这也是一个声明。 x = 1
是一个有效的语句,因为已经声明了var x
。它也是值为1的表达式,然后再次分配给x
。
答案 2 :(得分:12)
在java或任何现代语言中,赋值来自右侧。
假设您有两个变量x和y,
int z = x = y = 5;
此语句有效,这是编译器分割它们的方式。
y = 5;
x = y;
z = x; // which will be 5
但在你的情况下
int x = x + 1;
编译器给出了一个例外,因为它会像这样分裂。
x = 1; // oops, it isn't declared because assignment comes from the right.
答案 3 :(得分:8)
int x = x = 1;
不等于:
int x;
x = 1;
x = x;
javap再次帮助我们,这些是为此代码生成的JVM指令:
0: iconst_1 //load constant to stack
1: dup //duplicate it
2: istore_1 //set x to constant
3: istore_1 //set x to constant
更像是:
int x = 1;
x = 1;
这里没有理由抛出未定义的引用错误。现在在它的初始化之前使用变量,因此该代码完全符合规范。 实际上根本没有使用变量,只是分配。而且JIT编译器会更进一步,它将消除这种结构。说实话,我不明白这段代码是如何与JLS的变量初始化和使用规范相关联的。没用就没问题。 ;)
如果我错了,请更正。我无法弄清楚为什么其他答案,涉及许多JLS段落收集了这么多的优点。这些段落与本案没有任何共同之处。只需两个连续作业即可。
如果我们写:
int b, c, d, e, f;
int a = b = c = d = e = f = 5;
等于:
f = 5
e = 5
d = 5
c = 5
b = 5
a = 5
最右边的表达式只是逐个分配给变量,没有任何递归。我们可以以任何方式混淆变量:
a = b = c = f = e = d = a = a = a = a = a = e = f = 5;
答案 4 :(得分:7)
在int x = x + 1;
中,您向x添加1,那么x
的值是多少,它尚未创建。
但是在int x=x=1;
中编译时没有错误,因为您将1分配给x
。
答案 5 :(得分:5)
您的第一段代码包含第二段=
而不是加号。这将在任何地方编译,而第二段代码不会在任何一个地方编译。
答案 6 :(得分:5)
在第二段代码中,x在声明之前使用,而在第一段代码中,它只被分配了两次,没有意义但是有效。
答案 7 :(得分:5)
让我们一步一步地分解,正确的联想
int x = x = 1
x = 1
,将1分配给变量x
int x = x
,将x指定为自身,作为int。由于x以前被指定为1,因此它保留1,尽管是多余的。
编译好。
int x = x + 1
x + 1
,将一个添加到变量x。但是,x未定义,这将导致编译错误。
int x = x + 1
,因此这行编译错误,因为equals的右边部分不会编译,将一个添加到未分配的变量
答案 8 :(得分:3)
第二个int x=x=1
是编译因为你将值赋给x但是在其他情况下int x=x+1
这里变量x没有被初始化,记住在java局部变量中没有初始化为默认值。
注意如果在类范围内它(int x=x+1
)也会因为未创建变量而产生编译错误。
答案 9 :(得分:2)
int x = x + 1;
在Visual Studio 2008中成功编译并发出警告
warning C4700: uninitialized local variable 'x' used`
答案 10 :(得分:2)
答案 11 :(得分:2)
由于代码的实际工作方式,代码行无法编译并发出警告。
运行代码int x = x = 1
时,Java首先按照定义创建变量x
。 然后它会运行分配代码(x = 1
)。由于已定义x
,因此系统没有错误将x
设置为1.这将返回值1,因为现在是x
的值。因此,x
现在最终设为1.
Java基本上执行代码,就像这样:
int x;
x = (x = 1); // (x = 1) returns 1 so there is no error
但是,在您的第二段代码int x = x + 1
中,+ 1
语句需要定义x
,到那时它不是。{1}}。由于赋值语句始终意味着首先运行=
右侧的代码,因此代码将失败,因为x
未定义。 Java将运行如下代码:
int x;
x = x + 1; // this line causes the error because `x` is undefined
答案 12 :(得分:-1)
编译器从右到左阅读语句,我们的目的是做相反的事情。这就是为什么它一开始很恼火。从右到左让这个习惯读取语句(代码),你就不会遇到这样的问题。