实例变量定义和实例块

我有以下代码 –

{s = "Hello";} String s; 

这编译得很好,这意味着变量定义在实例阻塞之前执行。 但是,如果我使用以下代码,则不会编译(“错误:非法转发引用”)。

 {s = "Hello"; String ss = s;} String s; 

因此,在变量定义之前出现的实例块中,不可能在语句的右侧使用’s’的值。 对幕后发生的事情有一个明智的解释,还是这只是Java的特殊function?

PS我之前看过一个类似的问题,唯一的解释是它是Java的一个特性。 我写这篇文章是为了询问社区,这是否确实是这个问题的最后一句话。

JLS§8.3.3(“现场初始化期间的前向参考”)在这里阐述了一些内容:

使用在使用后以声明方式显示声明的实例变量有时会受到限制,即使这些实例变量在范围内也是如此。 具体来说,如果满足以下所有条件,则为编译时错误:

  • 在使用实例变量之后,类或接口C中的实例变量的声明以文本forms出现;

  • 在C的实例变量初始值设定项或C的实例初始值设定项中使用是一个简单的名称;

  • 使用不在作业的左侧;

  • C是封闭使用的最内层类或接口。

第一颗子弹将适用于您的示例。

至于“为什么”部分,“为什么”通常是一个棘手的语言设计问题,但在这种情况下,他们有助于进一步向下添加这个注释:

上述限制旨在在编译时捕获循环或其他格式错误的初始化。

在第二种情况下,您将得到编译错误IllegalForwardReference,因为变量s的使用不在赋值的左侧,并且JLS明确指出它是导致IllegalForwardReference错误的原因之一

我只能告诉你:编译器将所有初始化代码移动到构造函数体的末尾 (为每个构造函数重复代码)。 反编译一个例子就会显示出来。

所以,你必须意识到,通过这种方式,某些变量的声明顺序在将其作为右侧进行评估时很重要,即使在将其作为左侧进行评估时无关紧要。

摆脱这些不连贯性的一种方法是将范围“this”预先挂起到每个实例变量。