Instance Variable Definitions and Instance Blocks

I have the following code -

{s = "Hello";} String s; 

This compiles the penalty, implying that variable definitions are executed before the instance blocks. However, if I use the following code instead, it does not compile ("error: illegal direct link").

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

Thus, it is impossible to use the value 's' on the right side of the instruction in the instance block that comes before the variable definition. Is there any reasonable explanation for what happens behind the scenes, or is it just an unusual feature of Java?

PS I saw a similar question asked earlier, the only explanation given here is a feature of Java. I am writing this to ask the community if this is really the last word on this issue.

+6
source share
3 answers

JLS ยง8.3.3 ("Direct links during field initialization") sheds light here:

The use of instance variables whose declarations appear in the text after use are sometimes limited, although these instance variables are in scope. In particular, this is a compile-time error if all of the following conditions are true:

  • An instance variable declaration in a class or C interface appears after using an instance variable text

  • Usage is a simple name either in the C instance variable initializer or in the C instance initializer;

  • Use is not on the left side of the assignment;

  • C is the innermost class or interface that spans usage.

The first bullet is applicable to your example.

As for the why, why is usually a tricky question with the design of the language, but in this case they added this note further:

The limitations given above are intended for catching, during compilation, cyclic or incorrect initializations.

+3
source

In the second case, you will receive a IllegalForwardReference compilation error due to the fact that the use of the variable s not on the left side of the destination, and JLS explicitly states this as one of the reasons for receiving the IllegalForwardReference error

0
source

I just can tell you the following: the compiler translates all the initialization code to the end of the body of the constructors (repeating the code for each constructor). Decompiling an example would show this.

So, you should understand that in this way the declaration order of a variable is important when evaluating it as the right-hand side, even if it does not matter when evaluating it as the left-hand side.

One way to get rid of these inconsistencies is to pre-substitute the "this" region with each instance variable.

0
source

Source: https://habr.com/ru/post/975435/


All Articles