Ich habe ein Java-Programm, das so aussieht.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Was LocalScreen.thisbedeutet in aFuncCall?
Ich habe ein Java-Programm, das so aussieht.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Was LocalScreen.thisbedeutet in aFuncCall?
Antworten:
LocalScreen.thisbezieht sich auf thisdie 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.thisin Ihrem Beispiel nicht definiert. Ich weiß nicht, ob diese Einschränkung für Bytecode gilt. Vielleicht nicht.
Es bedeutet die thisInstanz der äußeren LocalScreenKlasse.
Wenn Sie thisohne 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.thisErmö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.thisund thisin 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.thisZeigen 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.thisinrun()an der verweisen umschließendena‚sthis. Habe ich recht? (So ist der minimierte Code in den.jarDateien der OSX Kindle Previewer-App . Ich versuche nur zu verstehen, was ich sehe.)