Java: Class.this
У меня есть программа на Java, которая выглядит следующим образом.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Что значит LocalScreen.this
означает в aFuncCall
?
5 ответов
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
Этот пост был переписан как статья здесь.
Это означает 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.
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
выходит за рамки анонимной новой операции.