У меня есть программа на 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 , я просто пытаюсь понять, на что я смотрю.)