java - Instance initializer and *this* keyword -


this question has answer here:

trying compile piece of code

public class main {      public static void main(string args[]) {             new main();     }      { system.out.println(x); } //error here      int x=1; } 

produces cannot reference field before defined error. if change initializer row to

    { system.out.println(this.x); } 

it works charm, printing default int value 0.

this bit confusing me, why this makes difference? shouldn't redundant in case? can explain me happens behind scenes make clear how works?

ps: know declaring x before initializer make work too.

i try explain on compiler layer.

say have method like:

int x; x = 1; system.out.println(x); 

the compilation succed , execution well. if change method this:

system.out.println(x); int x; x = 1; 

it not compile same given example.

the compiler copies code of { } intializer ctor , x=1 initialization.

as said works if set x=1 before { } intializer.

public class mainc {      public static void main(string args[]) {             new mainc();     }      int x=1;     {       system.out.println(x);     } } 

see following java bytecode:

  public mainc();     descriptor: ()v     flags: acc_public     code:       stack=2, locals=1, args_size=1          0: aload_0          1: invokespecial #1                  // method java/lang/object."<init>":()v          4: aload_0          5: iconst_1          6: putfield      #2                  // field x:i          9: getstatic     #3                  // field java/lang/system.out:ljava/io/printstream;         12: aload_0         13: getfield      #2                  // field x:i         16: invokevirtual #4                  // method java/io/printstream.println:(i)v         19: return       linenumbertable:         line 1: 0         line 7: 4         line 9: 9         line 10: 19 

the field x declared , gets value 1 before used in system.out.println call.

so why doesn't work if set after { } same reason cant use code of second example. field declared after usage makes no sense.

so why works this keyword?!

lets code:

public class main {      public static void main(string args[]) {             new main();     }      { system.out.println(this.x); } //error here      int x=1; } 

the corresponding java bytecode ctor:

  public main();     descriptor: ()v     flags: acc_public     code:       stack=2, locals=1, args_size=1          0: aload_0          1: invokespecial #1                  // method java/lang/object."<init>":()v          4: getstatic     #2                  // field java/lang/system.out:ljava/io/printstream;          7: aload_0          8: getfield      #3                  // field x:i         11: invokevirtual #4                  // method java/io/printstream.println:(i)v         14: aload_0         15: iconst_1         16: putfield      #3                  // field x:i         19: return       linenumbertable:         line 1: 0         line 7: 4         line 9: 14 

so whats happens here? easy speaking this keyword loads main object reference on stack. after field x can accessed system.out.println call can executed successfully.


Comments

Popular posts from this blog

powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment -

twig - Using Twigbridge in a Laravel 5.1 Package -

c# - LINQ join Entities from HashSet's, Join vs Dictionary vs HashSet performance -