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
Post a Comment