普通的this 在真正的Java 代码中永远不可能是null1,而您的示例使用普通的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)
表明我们尝试创建带有 null 引用的 Inner 到其 Outer 的尝试失败了。
事实上,如果你坚持“纯 Java”信封,你就无法打破它。
但是,每个Inner 实例都有一个隐藏的final 合成字段(称为"this$0"),其中包含对Outer 的引用。如果您真的很棘手,可以使用“非纯”的方式将null 分配给该字段。
- 您可以使用
Unsafe 来执行此操作。
- 您可以使用本机代码(例如 JNI)来执行此操作。
- 您可以使用反射来做到这一点。
无论您采用哪种方式,最终结果都是Outer.this 表达式的计算结果为null2。
简而言之,合格的this有可能为null。但如果您的程序遵循“纯 Java”规则,则不可能。
1 - 我对诸如手动“编写”字节码并将它们作为真正的 Java 传递、使用 BCEL 或类似方法调整字节码、或跳入本机代码并使用保存的寄存器等技巧打折扣。 IMO,那不是 Java。假设,这样的事情也可能由于 JVM 错误而发生......但我不记得每一次看到的错误报告。
2 - 实际上,JLS 并没有说明行为将是什么,它可能取决于实现......除其他外。