Ich habe ein Java-Programm, das so aussieht.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Was LocalScreen.this
bedeutet in aFuncCall
?
Ich habe ein Java-Programm, das so aussieht.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Was LocalScreen.this
bedeutet in aFuncCall
?
Antworten:
LocalScreen.this
bezieht sich auf this
die einschließende Klasse.
Dieses Beispiel sollte es erklären:
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();
}
}
Ausgabe:
An anonymous Runnable!
A LocalScreen object
Dieser Beitrag wurde bereits als ein Artikel neu geschrieben hier .
a.this
in Ihrem Beispiel nicht definiert. Ich weiß nicht, ob diese Einschränkung für Bytecode gilt. Vielleicht nicht.
Es bedeutet die this
Instanz der äußeren LocalScreen
Klasse.
Wenn Sie this
ohne Qualifizierer schreiben, wird die Instanz der inneren Klasse zurückgegeben , in der sich der Aufruf befindet.
Der Compiler nimmt den Code und macht so etwas damit:
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!";
}
}
Wie Sie sehen können, konvertiert der Compiler eine innere Klasse in eine äußere Klasse (dies war eine Entwurfsentscheidung, die vor langer Zeit getroffen wurde, sodass VMs nicht geändert werden mussten, um innere Klassen zu verstehen).
Wenn eine nicht statische innere Klasse erstellt wird, benötigt sie einen Verweis auf das übergeordnete Element, damit sie Methoden / Zugriffsvariablen der äußeren Klasse aufrufen kann.
Da dies innerhalb der inneren Klasse nicht der richtige Typ ist, müssen Sie Zugriff auf die äußere Klasse erhalten, um den richtigen Typ für den Aufruf der onMake-Methode zu erhalten.
new LocalScreen$1().run;
sein new LocalScreen$1(this).run;
?
Class.this
Ermöglicht den Zugriff auf die Instanz der äußeren Klasse. Siehe folgendes Beispiel.
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();
}
}
Dann wirst du bekommen.
D: a-b-c-d
C: a-b-c
B: a-b
A: a
Ich weiß, was Ihre Verwirrung ist. Ich bin gerade auf das Problem gestoßen, es sollte eine spezielle Szene haben, um sie zu unterscheiden.
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.##")
}
}
Sie können den Unterschied zwischen THIS.this
und this
in der neuen DIESEN Operation anhand des Hashcodes (. ##) erkennen.
Test in der Scala-Konsole:
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
Zeigen Sie immer auf die äußere DIESE Klasse, auf die durch val x verwiesen wird, die jedoch this
über eine anonyme neue Operation hinausgeht.
public class a { private class a { public void run() { System.out.println(a.this.toString()); } }
Ich nehme an, dass es die gleiche Sache ist; diea.this
inrun()
an der verweisen umschließendena
‚sthis
. Habe ich recht? (So ist der minimierte Code in den.jar
Dateien der OSX Kindle Previewer-App . Ich versuche nur zu verstehen, was ich sehe.)