Surprised cat

A typical scenario when creating a new class is to declare and initialize some fields:

I realize that initial values of these fields are correlated and I update the code:

If I’m not careful, I can even try:

but this won’t compile because it is a forward reference during field initialization:

  • The declaration of an instance variable in a class or interface C appears textually after a use of the instance variable;
  • The use is a simple name in either an instance variable initializer of C or an instance initializer of C;
  • The use is not on the left hand side of an assignment;
  • C is the innermost class or interface enclosing the use.

It is easy to understand even without this documentation because it’s commons sense. I need to declare a variable before I can use it. This was clear for me until I saw this code:

Surprisingly this code compiles and displays:

The question is why is this working? I would expect a compile time error. After reading more careful the rules about forward reference during field initialization, the catch is on the second line:

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

In this example I’m using this.value and not the simple name value and that’s why it works. What really happens when creating a new instance of DeclarationAndInitializationGoCrazy is:

  • Field value is set to default value 0
  • Field value is initialized with 0 + 1 which is 1

I can go really crazy and try something like:

that compiles and displays:

It is the same explanation as on previous example:

  • Fields value1 and value2 are set to default value 0
  • Field value1 is initialized with 0 + 1 which is 1
  • Field value2 is initialized with 1 + 1 which is 2

I don’t see now any practical reason why I would do this in a real project code, at least it was a fun thing to do.

Image credit: cristofer angello caballero thorne, CC0 Public Domain