J'ai un programme Java qui ressemble à ceci.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Que LocalScreen.this
signifie dans aFuncCall
?
J'ai un programme Java qui ressemble à ceci.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Que LocalScreen.this
signifie dans aFuncCall
?
Réponses:
LocalScreen.this
fait référence à this
la classe englobante.
Cet exemple devrait l'expliquer:
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();
}
}
Production:
An anonymous Runnable!
A LocalScreen object
Cet article a été réécrit sous forme d'article ici .
a.this
dans votre exemple n'est pas définie. Je ne sais pas si cette contrainte est vraie pour le bytecode. Peut être pas.
Cela signifie l' this
instance de la LocalScreen
classe externe .
L'écriture this
sans qualificatif retournera l'instance de la classe interne dans laquelle l'appel se trouve.
Le compilateur prend le code et fait quelque chose comme ça avec:
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!";
}
}
Comme vous pouvez le voir, lorsque le compilateur prend une classe interne, il la convertit en classe externe (il s'agissait d'une décision de conception prise il y a LONGTEMPS afin que les machines virtuelles n'aient pas besoin d'être modifiées pour comprendre les classes internes).
Lorsqu'une classe interne non statique est créée, elle a besoin d'une référence au parent pour pouvoir appeler des méthodes / accéder aux variables de la classe externe.
Le this à l'intérieur de ce qui était la classe interne n'est pas le type approprié, vous devez accéder à la classe externe pour obtenir le bon type pour appeler la méthode onMake.
new LocalScreen$1().run;
être new LocalScreen$1(this).run;
?
Class.this
autorise l'accès à l'instance de la classe externe. Voir l'exemple suivant.
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();
}
}
Ensuite, vous obtiendrez.
D: a-b-c-d
C: a-b-c
B: a-b
A: a
Je sais quelle est votre confusion. Je rencontre le problème tout à l'heure, il devrait avoir une scène spéciale pour les distinguer.
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.##")
}
}
Vous pouvez voir la différence entre THIS.this
et this
dans la nouvelle opération THIS par hashcode (. ##)
test dans la console scala:
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
pointez toujours vers la classe THIS externe qui est référencée par val x, mais qui this
est au-delà de la nouvelle opération anonyme.
public class a { private class a { public void run() { System.out.println(a.this.toString()); } }
je suppose que c'est la même chose; l'a.this
intérieur derun()
doit se référer à la englobantea
« sthis
. Ai-je raison? (C'est ainsi que le code minifié est dans les.jar
fichiers de l'application OSX Kindle Previewer , j'essaie juste de comprendre ce que je regarde.)