Java: Class.this

Ho un programma Java simile a questo.

public class LocalScreen { public void onMake() { aFuncCall(LocalScreen.this, oneString, twoString); } } 

Che cosa significa aFuncCall in aFuncCall ?

LocalScreen.this riferisce a this della class che racchiude.

Questo esempio dovrebbe spiegarlo:

 public class LocalScreen { public void method() { new Runnable() { public void run() { // Prints "An anonymous Runnable" System.out.println(this.toString()); // Prints "A LocalScreen object" System.out.println(LocalScreen.this.toString()); // Won't compile! 'this' is a Runnable! //onMake(this); // Compiles! Refers to enclosing object onMake(LocalScreen.this); } public String toString() { return "An anonymous Runnable!"; } }.run(); } public String toString() { return "A LocalScreen object"; } public void onMake(LocalScreen ls) { /* ... */ } public static void main(String[] args) { new LocalScreen().method(); } } 

Produzione:

 An anonymous Runnable! A LocalScreen object 

Questo post è stato riscritto come articolo qui .

Significa this istanza della class LocalScreen esterna.

Scrivendo this senza un qualificatore restituirai l’istanza della class interna in cui si trova la chiamata.

Il compilatore prende il codice e fa qualcosa del genere con esso:

 public class LocalScreen { public void method() { new LocalScreen$1(this).run; } public String toString() { return "A LocalScreen object"; } public void onMake(LocalScreen ls) { /* ... */ } public static void main(String[] args) { new LocalScreen().method(); } } class LocalScreen$1 extends Runnable { final LocalScreen $this; LocalScreen$1(LocalScreen $this) { this.$this = $this; } public void run() { // Prints "An anonymous Runnable" System.out.println(this.toString()); // Prints "A LocalScreen object" System.out.println($this.toString()); // Won't compile! 'this' is a Runnable! //onMake(this); // Compiles! Refers to enclosing object $this.onMake($this); } public String toString() { return "An anonymous Runnable!"; } } 

Come si può vedere, quando il compilatore prende una class interna, la converte in una class esterna (questa è stata una decisione di progettazione presa molto tempo fa in modo che le VM non avessero bisogno di essere cambiate per comprendere le classi interne).

Quando viene creata una class interna non statica, ha bisogno di un riferimento al genitore in modo che possa chiamare metodi / variabili di accesso della class esterna.

Questo all’interno di quella che era la class interna non è il tipo corretto, è necessario accedere alla class esterna per ottenere il tipo giusto per chiamare il metodo onMake.

Class.this consente l’accesso all’istanza della class esterna. Vedi il seguente esempio.

 public class A { final String name; final B b; A(String name) { this.name = name; this.b = new B(name + "-b"); } class B { final String name; final C c; B(String name) { this.name = name; this.c = new C(name + "-c"); } class C { final String name; final D d; C(String name) { this.name = name; this.d = new D(name + "-d"); } class D { final String name; D(String name) { this.name = name; } void printMe() { System.out.println("D: " + D.this.name); // `this` of class D System.out.println("C: " + C.this.name); // `this` of class C System.out.println("B: " + B.this.name); // `this` of class B System.out.println("A: " + A.this.name); // `this` of class A } } } } static public void main(String ... args) { final A a = new A("a"); abcdprintMe(); } } 

Allora otterrai.

 D: abcd C: abc B: ab A: a 

So qual è la tua confusione.Io incontro il problema proprio ora, dovrebbe avere una scena speciale per distinguerli.

 class THIS { def andthen = { new THIS { println(THIS.this.## + ":inner-THIS.this.##") println(this.## + ":inner-this.##") new THIS { println(THIS.this.## + ":inner-inner-THIS.this.##") println(this.## + ":inner-this.##") } } } def getInfo = { println(THIS.this.## + ":THIS.this.##") println(this.## + ":this.##") } } 

Puoi vedere la diff tra THIS.this e this in new THIS operation di hashcode (. ##)

test in scala console:

 scala> val x = new THIS x: THIS = [email protected] scala> val y = x.andthen 1522119751:inner-THIS.this.## 404586280:inner-this.## 1522119751:inner-inner-THIS.this.## 2027227708:inner-this.## y: THIS = [email protected] scala> x.getInfo 1522119751:THIS.this.## 1522119751:this.## 

THIS.this sempre questa class esterna che è riferita da val x, ma this è al di là della nuova operazione anonima.