ฉันมีโปรแกรม 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
ในตัวอย่างของคุณไม่ได้กำหนดไว้ ฉันไม่รู้ว่าข้อ จำกัด นี้เป็นจริงสำหรับ bytecode หรือไม่ อาจจะไม่.
มันหมายถึง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!";
}
}
อย่างที่คุณเห็นเมื่อคอมไพเลอร์ใช้คลาสภายในมันจะแปลงเป็นคลาสภายนอก (นี่เป็นการตัดสินใจออกแบบเมื่อนานมาแล้วดังนั้น VMs จึงไม่จำเป็นต้องเปลี่ยนเพื่อทำความเข้าใจคลาสภายใน)
เมื่อสร้างคลาสภายในที่ไม่คงที่จำเป็นต้องมีการอ้างอิงถึงพาเรนต์เพื่อให้สามารถเรียกใช้วิธีการ / เข้าถึงตัวแปรของคลาสภายนอกได้
ภายในของสิ่งที่เป็นคลาสภายในไม่ใช่ประเภทที่เหมาะสมคุณต้องเข้าถึงคลาสด้านนอกเพื่อให้ได้ประเภทที่เหมาะสมสำหรับการเรียกใช้เมธอด 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> 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()
ต้องดูที่การปิดล้อม 'sa
this
ฉันถูกไหม? (นี่คือวิธีที่โค้ดย่อขนาดใน.jar
ไฟล์ของแอพ OSX Kindle Previewer ฉันแค่พยายามเข้าใจสิ่งที่ฉันกำลังดูอยู่)