Java:类.this
Posted
技术标签:
【中文标题】Java:类.this【英文标题】:Java: Class.this 【发布时间】:2011-07-28 15:58:33 【问题描述】:我有一个类似这样的 Java 程序。
public class LocalScreen
public void onMake()
aFuncCall(LocalScreen.this, oneString, twoString);
LocalScreen.this
在aFuncCall
中是什么意思?
【问题讨论】:
【参考方案1】: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
本帖已改写为文章here。
【讨论】:
如果你有类似的东西怎么办:public class a private class a public void run() System.out.println(a.this.toString());
我想这是同样的事情; run()
中的a.this
必须引用封闭 a
的this
。我对吗? (这就是 OSX Kindle Previewer 应用程序的 .jar
文件中的缩小代码,我只是想了解我在看什么。)
在 Java 中,内部类的名称可能与其任何封闭类 (JLS 8.1) 的名称不同,因此您的示例中的 a.this
未定义。我不知道这个约束是否适用于字节码。也许不是。【参考方案2】:
表示外部LocalScreen
类的this
实例。
编写不带限定符的this
将返回调用所在的inner class 的实例。
【讨论】:
还是不太明白。与“this”相比,将其编码为“LocalScreen.this”有什么区别?我测试了两者,编译器只接受“LocalScreen.this”。 aFuncCall 的第一个参数需要一个Parent 类,它是“Somethig”的父类。 我也很好奇这个。您能否详细说明这意味着什么?我没有看到上面代码中定义的任何内部类;是否每个 Java 函数都有一个与其所属的类分开的关联匿名类? @rascher:有内部类在使用; OP 没有将它们包含在代码 sn-p 中。此语法仅在非静态内部类中受支持。 很高兴您提供了官方 Java 文档的链接。【参考方案3】:编译器获取代码并对其执行类似的操作:
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!";
如您所见,当编译器采用内部类时,它会将其转换为外部类(这是很久以前做出的设计决定,因此不需要更改 VM 即可理解内部类)。
当创建一个非静态内部类时,它需要一个对父级的引用,以便它可以调用外部类的方法/访问变量。
内部类的 this 不是正确的类型,您需要访问外部类以获得正确的类型来调用 onMake 方法。
【讨论】:
不应该是new LocalScreen$1().run;
是new LocalScreen$1(this).run;
?
这是一个被低估的问题答案。有趣的东西。【参考方案4】:
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 允许访问外部类的实例”而不是“Class.this 允许访问外部类的 this”之类的东西.一个类没有任何“this”,只有实例有才能引用自己...【参考方案5】:我知道你的困惑是什么。我刚刚遇到这个问题,应该有特殊的场景来区分它们。
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
和 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
始终指向外部 THIS 类,由 val x 引用,但 this
超出了匿名新操作的范围。
【讨论】:
以上是关于Java:类.this的主要内容,如果未能解决你的问题,请参考以下文章