您的情况相当于
String str;
str = (str = "hello");
虽然这些任务看起来很有趣,但从概念上讲并没有什么问题。
然而,引用自身的变量初始化显然不是一个好主意。编译器会在可能是程序员错误的情况下尝试标记它;有时编译器无法标记它;有时编译器也会过度标记它。
局部变量有比字段变量更严格的要求——必须在使用其值之前先进行赋值。例如,以下代码将无法编译,因为局部变量在被分配之前就被读取了。
String str; // local variable
str = str; // error, try to read `str` before it's assigned
一个字段变量总是有一个默认的初始值;然而,编译器会检查明显的程序员错误。
int x = x+1
但是如果这样的检查失败也不会造成灾难,因为在显式赋值之前x
的值为0
int x;
{ x=x+1; } // ok. x==0, then x==1 after assignment
然而,如果
x
是
final
,上述代码会失败,因为编译器要求在读取
x
之前先确定赋值。对于局部变量也有相同的要求。但是这种检查可以被绕过,因为对于字段变量来说,完全分析和防止它是不可能的。
final int x = (this).x+1; // compiles!
在某些情况下,编译器过于苛刻,阻止了涉及lambda的合理使用情况。
Runnable r1 = ()->System.out.println(r1)
这个用例在概念上并没有问题;它可以通过(this).
来规避。