Ho un programma Java simile a questo.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Cosa LocalScreen.this
significa in aFuncCall
?
Ho un programma Java simile a questo.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Cosa LocalScreen.this
significa in aFuncCall
?
Risposte:
LocalScreen.this
si riferisce alla this
classe allegata.
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 .
a.this
nel tuo esempio non è definita. Non so se questo vincolo sia vero per bytecode. Forse no.
Significa l' this
istanza della LocalScreen
classe esterna .
La scrittura this
senza un qualificatore restituirà l'istanza della classe 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 puoi vedere, quando il compilatore prende una classe interna, la converte in una classe esterna (questa era una decisione di progettazione presa molto tempo fa in modo che le VM non dovevano essere modificate per comprendere le classi interne).
Quando viene creata una classe interna non statica, è necessario un riferimento al genitore in modo che possa chiamare metodi / variabili di accesso della classe esterna.
Questo all'interno di quella che era la classe interna non è del tipo corretto, è necessario accedere alla classe esterna per ottenere il tipo giusto per chiamare il metodo onMake.
new LocalScreen$1().run;
essere new LocalScreen$1(this).run;
?
Class.this
consente l'accesso all'istanza della classe 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");
a.b.c.d.printMe();
}
}
Allora otterrai.
D: a-b-c-d
C: a-b-c
B: a-b
A: a
So qual è la tua confusione. Sto incontrando 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 differenza tra THIS.this
e this
nella nuova QUESTA operazione tramite hashcode (. ##)
test in scala console:
scala> val x = new THIS
x: THIS = THIS@5ab9b447
scala> val y = x.andthen
1522119751:inner-THIS.this.##
404586280:inner-this.##
1522119751:inner-inner-THIS.this.##
2027227708:inner-this.##
y: THIS = THIS$$anon$1@181d7f28
scala> x.getInfo
1522119751:THIS.this.##
1522119751:this.##
THIS.this
punta sempre a QUESTA classe esterna a cui fa riferimento val x, ma this
è al di là di una nuova operazione anonima.
public class a { private class a { public void run() { System.out.println(a.this.toString()); } }
suppongo che sia la stessa cosa; ila.this
raggiorun()
deve fare riferimento alla racchiudea
s'this
. Ho ragione? (Ecco come si trova il codice minimizzato nei file dell'app OSX Kindle Previewer.jar
, sto solo cercando di capire cosa sto guardando.)