实例变量定义和实例块

时间:2014-09-17 16:13:41

标签: java

我有以下代码 -

{s = "Hello";}
String s;

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

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

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

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

3 个答案:

答案 0 :(得分:3)

JLS §8.3.3 ("Forward References During Field Initialization")在这里阐明了一些亮点:

  

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

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

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

  •   
  • 使用不在作业的左侧;

  •   
  • C是封闭使用的最里面的类或接口。

  •   

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

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

  

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

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

摆脱这些不连贯性的一种方法是预先扩大范围"这个"到每个实例变量。