У меня есть программа на Java, которая выглядит так.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Что LocalScreen.this
значит в aFuncCall
?
У меня есть программа на Java, которая выглядит так.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Что LocalScreen.this
значит в aFuncCall
?
Ответы:
LocalScreen.this
относится к this
включающему классу.
Этот пример должен объяснить это:
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();
}
}
Вывод:
An anonymous Runnable!
A LocalScreen object
Это сообщение было переписано как статья здесь .
a.this
в вашем примере не определен. Я не знаю, верно ли это ограничение для байт-кода. Может быть нет.
Это означает this
экземпляр внешнего LocalScreen
класса.
Запись this
без квалификатора вернет экземпляр внутреннего класса , внутри которого находится вызов.
Компилятор берет код и делает с ним примерно следующее:
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!";
}
}
Как вы можете видеть, когда компилятор принимает внутренний класс, он преобразует его во внешний класс (это было дизайнерское решение, принятое ДЛИННО назад, поэтому не нужно было менять виртуальные машины для понимания внутренних классов).
Когда создается нестатический внутренний класс, ему нужна ссылка на родительский объект, чтобы он мог вызывать методы / переменные доступа внешнего класса.
Это внутри того, что было внутренним классом, не является правильным типом, вам нужно получить доступ к внешнему классу, чтобы получить правильный тип для вызова метода onMake.
new LocalScreen$1().run;
быть new LocalScreen$1(this).run;
?
Class.this
разрешает доступ к экземпляру внешнего класса. См. Следующий пример.
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();
}
}
Тогда получите.
D: a-b-c-d
C: a-b-c
B: a-b
A: a
Я знаю, в чем ваше замешательство. Я столкнулся с проблемой только сейчас, у нее должна быть специальная сцена, чтобы их различать.
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.##")
}
}
Вы можете увидеть разницу между THIS.this
и this
в новой ЭТОЙ операции по хэш-коду (. ##)
тест в консоли 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
всегда указывают на внешний ЭТОЙ класс, на который ссылается val x, но this
не на анонимную новую операцию.
public class a { private class a { public void run() { System.out.println(a.this.toString()); } }
Я полагаю, что это то же самое;a.this
внутриrun()
должен относиться к ограждающимa
«Sthis
. Я прав? (Вот как миниатюрный код находится в.jar
файлах приложения OSX Kindle Previewer , я просто пытаюсь понять, на что я смотрю.)