ปกติthisไม่สามารถnullอยู่ในโค้ด Java 1จริงได้และตัวอย่างของคุณใช้แบบปกติthisและตัวอย่างของคุณใช้ตามปกติดูคำตอบอื่น ๆ สำหรับรายละเอียดเพิ่มเติม
ที่มีคุณภาพและthis ควรไม่เป็นnullแต่เป็นไปได้ที่จะทำลายนี้ พิจารณาสิ่งต่อไปนี้:
public class Outer {
public Outer() {}
public class Inner {
public Inner() {}
public String toString() {
return "outer is " + Outer.this; // Qualified this!!
}
}
}
เมื่อเราต้องการสร้างอินสแตนซ์Innerเราต้องทำสิ่งนี้:
public static void main(String[] args) {
Outer outer = new Outer();
Inner inner = outer.new Inner();
System.out.println(inner);
outer = null;
inner = outer.new Inner(); // FAIL ... throws an NPE
}
ผลลัพธ์คือ:
outer is Outer@2a139a55
Exception in thread "main" java.lang.NullPointerException
at Outer.main(Outer.java:19)
แสดงว่าความพยายามของเราในการสร้างInnerโดยnullอ้างอิงถึงOuterล้มเหลว
ในความเป็นจริงถ้าคุณติดภายในซอง "Pure Java" คุณจะไม่สามารถทำลายสิ่งนี้ได้
อย่างไรก็ตามแต่ละInnerอินสแตนซ์มีfinalฟิลด์สังเคราะห์ที่ซ่อนอยู่(เรียกว่า"this$0") ซึ่งมีการอ้างอิงถึงไฟล์Outer. หากคุณมีเล่ห์เหลี่ยมจริงๆคุณสามารถใช้วิธี "ไม่บริสุทธิ์" เพื่อกำหนดnullให้กับฟิลด์ได้
- คุณสามารถใช้
Unsafeเพื่อทำมัน
- คุณสามารถใช้โค้ดเนทีฟ (เช่น JNI) เพื่อทำได้
- คุณสามารถทำได้โดยใช้การสะท้อน
ไม่ว่าคุณจะทำด้วยวิธีใดผลลัพธ์สุดท้ายก็คือOuter.thisนิพจน์จะประเมินเป็นnull2 2
ในระยะสั้นจะเป็นไปได้สำหรับการที่มีคุณสมบัติที่จะเป็นthis nullแต่จะเป็นไปไม่ได้หากโปรแกรมของคุณปฏิบัติตามกฎ "Pure Java"
1 - ฉันลดกลเม็ดต่างๆเช่น "เขียน" bytecodes ด้วยมือและส่งต่อเป็น Java จริงปรับแต่ง bytecodes โดยใช้ BCEL หรือคล้ายกันหรือกระโดดลงในโค้ดเนทีฟและดำเนินการกับรีจิสเตอร์ที่บันทึกไว้ IMO นั่นไม่ใช่ Java สมมุติว่าสิ่งเหล่านี้อาจเกิดขึ้นเนื่องจากข้อบกพร่องของ JVM ... แต่ฉันจำไม่ได้ว่าทุกรายงานข้อผิดพลาด
2 - จริงๆแล้ว JLS ไม่ได้บอกว่าพฤติกรรมจะเป็นอย่างไรและอาจขึ้นอยู่กับการนำไปใช้ ... เหนือสิ่งอื่นใด