Boot Block

1

I'm studying for certification.

The book says that the declaration order of attributes and initialization blocks should be considered.

Scenario # 1: while doing this:

public class Teste {

    {
        System.out.println("Bloco: " + val);
    }

    private int val = 1;

    public int getVal() {
        return val;
    }

    public static void main(String[] args) {
        System.out.println("Val: " + new Teste().getVal());
    }
}

The program does not compile and displays the error: illegal forward reference .

Scenario # 2: while doing this:

public class Teste {

    {
        val = 2;
    }

    private int val = 1;

    public int getVal() {
        return val;
    }

    public static void main(String[] args) {
        System.out.println("Val: " + new Teste().getVal());
    }
}

The program compiles and runs Val: 1 .

Why can not I reference the variable val but can I assign a value to it?

In addition, if I was able to assign this value, why is the printed value different from the one assigned?

    
asked by anonymous 14.08.2017 / 21:09

2 answers

2
  

Why can not I reference the val variable but can I assign a value to it?

In short: before your statement you can assign a value to the variable, but do not use it.

The use before the declaration is described in the Java specification JLS 8.3.2 - Field initialization :

  

The initializer may use the simple name of any variable class declared in
  or inherited by the class, even one whose declaration occurs textually after   the initializer.

The next spec point says when you can not use an instance variable before the declaration JLS 8.3.3 - Forward References During Field Initialization :

  

... Specifically, it is a compile-time error if all of the following are true:      

  • The declaration of an instance variable in a class or interface C appears   textually after a use of the instance variable;

  •   
  • The use of a simple name in either an instance variable initializer of C or   an instance initializer of C;

  •   
  •   
  • C is the innermost class or interface enclosing the use.

  •   

Half complicated but in the background says that the use of the variable has to be on the left side of the equals ...

  

In addition, if I was able to assign this value, why is the printed value different from the one assigned?

Initialization of the instance occurs in the same order as the source code (left to right, top to bottom). Here again the JLS 12.5 specification. Creation of New Class Instances

  

4. Execute the instance initializers and instance variable initializers   for this class, ..., in the left-to-right order in which they appear textually   in the source code for the class.

(points 1-3 call the constructor of the parent class (super), point 5 constructor of the current class)

    
14.08.2017 / 23:31
1

Using the keys in both scenarios delimited the scope of the variable. The scope is the code snippet where the variable is still alive.

In scenario 1, the scope in which println was used did not define any variable with the name "val" and in addition the variable had not yet been initialized (put into memory). In scenario 2 the scope of the variable "private int val" is all class and the block is part of it, so java assigned 2 and then 1, after initialization the variable is in memory and therefore can be used by the methods. / p>     

14.08.2017 / 22:12