Tôi có một chương trình Java trông như thế này.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Điều gì có LocalScreen.this
nghĩa là trong aFuncCall
?
Tôi có một chương trình Java trông như thế này.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Điều gì có LocalScreen.this
nghĩa là trong aFuncCall
?
Câu trả lời:
LocalScreen.this
đề cập đến this
lớp bao quanh.
Ví dụ này sẽ giải thích nó:
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();
}
}
Đầu ra:
An anonymous Runnable!
A LocalScreen object
Bài đăng này đã được viết lại thành một bài báo ở đây .
a.this
trong ví dụ của bạn không được định nghĩa. Tôi không biết liệu ràng buộc này có đúng với bytecode hay không. Có thể không.
Nó có nghĩa là this
thể hiện của lớp bên ngoài LocalScreen
.
Việc ghi this
mà không có định nghĩa sẽ trả về thể hiện của lớp bên trong mà lệnh gọi nằm bên trong.
Trình biên dịch lấy mã và làm điều gì đó như thế này với nó:
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!";
}
}
Như bạn có thể thấy, khi trình biên dịch lấy một lớp bên trong, nó sẽ chuyển đổi nó thành lớp bên ngoài (đây là một quyết định thiết kế được đưa ra cách đây rất lâu để các máy ảo không cần phải thay đổi để hiểu các lớp bên trong).
Khi một lớp bên trong không tĩnh được tạo, nó cần một tham chiếu đến lớp cha để nó có thể gọi các phương thức / biến truy cập của lớp bên ngoài.
Phần bên trong của lớp bên trong không phải là kiểu thích hợp, bạn cần có quyền truy cập vào lớp bên ngoài để có được kiểu phù hợp để gọi phương thức onMake.
new LocalScreen$1().run;
nên new LocalScreen$1(this).run;
?
Class.this
cho phép truy cập vào thể hiện của lớp bên ngoài. Xem ví dụ sau.
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();
}
}
Sau đó, bạn sẽ nhận được.
D: a-b-c-d
C: a-b-c
B: a-b
A: a
Tôi biết sự nhầm lẫn của bạn là gì. Tôi gặp phải vấn đề vừa rồi, nó phải có cảnh đặc biệt để phân biệt chúng.
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.##")
}
}
Bạn có thể thấy sự khác biệt giữa THIS.this
và this
trong hoạt động NÀY mới bằng mã băm (. ##)
kiểm tra trong bảng điều khiển 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
luôn trỏ đến bên ngoài lớp NÀY được tham chiếu bởi val x, nhưng this
không phải là hoạt động mới ẩn danh.
public class a { private class a { public void run() { System.out.println(a.this.toString()); } }
Tôi cho rằng đó là vấn đề tương tự; cáca.this
bên trongrun()
phải tham khảo các kèm theoa
'sthis
. Tôi nói đúng chứ? (Đây là cách mã minified là trong ứng dụng của OSX Kindle previewer.jar
file, Tôi chỉ cố gắng để hiểu những gì tôi đang nhìn vào.)