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