Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what does "this" keyword mean in the initializer block? [duplicate]

Tags:

java

this

Here is my code:

class StaticBlock {
    {       
        println("initializer block : " + message);
    }
    public StaticBlock(String message) {
        this.message = message;
    }
    private String message;
}

Now the issue is that, in the initializer block

{       
    println("initializer block : " + message);
}

if I add the this keyword before message, it works, but there is an error when missing this keyword.

And the compiler says:

StaticBlockDemo.java:34: illegal forward reference
                println("initializer block : " + message);
                                                 ^
1 error

Why aren't they the same?

like image 486
Telerik Avatar asked Mar 08 '14 06:03

Telerik


People also ask

What does the this keyword do in Java?

The this keyword refers to the current object in a method or constructor. The most common use of the this keyword is to eliminate the confusion between class attributes and parameters with the same name (because a class attribute is shadowed by a method or constructor parameter).

What is the use of this keyword inside the init block?

In order to perform any operations while assigning values to an instance data member, an initializer block is used. In simpler terms, the initializer block is used to declare/initialize the common part of various constructors of a class. It runs every time whenever the object is created.

What is an initializer block?

Initializer block contains the code that is always executed whenever an instance is created. It is used to declare/initialise the common part of various constructors of a class. The order of initialization constructors and initializer block doesn't matter, initializer block is always executed before constructor.

What is instance initializer block in Java?

Instance Initializer block is used to initialize the instance data member. It run each time when object of the class is created. The initialization of the instance variable can be done directly but there can be performed extra operations while initializing the instance variable in the instance initializer block.


1 Answers

I don't know the design rationale, but it may help to read the relevant sections of the Java language specification.

8.6. Instance Initializers

Instance initializers are permitted to refer to the current object via the keyword this (§15.8.3), to use the keyword super (§15.11.2, §15.12), and to use any type variables in scope.

Use of instance variables whose declarations appear textually after the use is sometimes restricted, even though these instance variables are in scope. See §8.3.2.3 for the precise rules governing forward reference to instance variables.

8.3.2.3. Restrictions on the use of Fields during Initialization

The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:

  • The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.

  • The usage is not on the left hand side of an assignment.

  • The usage is via a simple name.

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

Here's the example from that section of the spec trimmed down to illustrate the specific point you're asking about:

class UseBeforeDeclaration {

    {
        j = 200;
          // ok - assignment
        j = j + 1;
          // error - right hand side reads before declaration
        int k = j = j + 1;
          // error - illegal forward reference to j
        int n = j = 300;
          // ok - j at left hand side of assignment
        int h = j++;
          // error - read before declaration
        int l = this.j * 3;
          // ok - not accessed via simple name
    }

    int j;
}

I should also note, though, that even the compiling version of your code isn't going to do what you want. If you run it:

new StaticBlock("abc");

It will print

initializer block : null

This is because initializers are executed before (most of) the constructor body. Here are the salient points from the spec:

12.5. Creation of New Class Instances

[...] the indicated constructor is processed to initialize the new object using the following procedure:

[...]

 4. Execute the instance initializers and instance variable initializers for this class [...]

 5. Execute the rest of the body of this constructor. [...]

like image 130
Chris Martin Avatar answered Oct 19 '22 02:10

Chris Martin