Normalny thisnigdy nie może być nullw prawdziwym kodzie Java 1 , a Twój przykład używa normalnego this. Zobacz inne odpowiedzi, aby uzyskać więcej informacji.
Kwalifikowany nigdy nie this powinien być null, ale można to przełamać. Rozważ następujące:
public class Outer {
public Outer() {}
public class Inner {
public Inner() {}
public String toString() {
return "outer is " + Outer.this; // Qualified this!!
}
}
}
Kiedy chcemy utworzyć instancję Inner, musimy to zrobić:
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
}
Wynik to:
outer is Outer@2a139a55
Exception in thread "main" java.lang.NullPointerException
at Outer.main(Outer.java:19)
pokazując, że nasza próba stworzenia Innerz nullodniesieniem do ich Outerzawiódł.
W rzeczywistości, jeśli trzymasz się obwiedni „czystej Javy”, nie możesz tego złamać.
Jednak każda Innerinstancja ma ukryte finalpole syntetyczne (nazywane "this$0"), które zawiera odwołanie doOuter . Jeśli jesteś naprawdę podstępny, możesz użyć "nieczystych" środków, aby przypisać nulldo pola.
- Możesz to
Unsafezrobić.
- Możesz do tego użyć kodu natywnego (np. JNI).
- Możesz to zrobić za pomocą refleksji.
Tak czy inaczej, efekt końcowy jest taki, że Outer.thiswyrażenie wyniesie null2 .
W skrócie, jest to możliwe dla wykwalifikowanego thisbyć null. Ale jest to niemożliwe, jeśli Twój program przestrzega zasad „czystej Java”.
1 - Dyskontuję sztuczki, takie jak „pisanie” kodów bajtowych ręcznie i przekazywanie ich jako prawdziwej Javy, poprawianie kodów bajtowych za pomocą BCEL lub podobnego, lub przeskakiwanie do kodu natywnego i manipulowanie zapisanymi rejestrami. IMO, czyli NIE JAVA. Hipotetycznie, takie rzeczy mogą się również zdarzyć w wyniku błędu JVM ... ale nie przypominam sobie, żeby każdy widział raporty o błędach.
2 - W rzeczywistości JLS nie mówi, jakie będzie zachowanie, i może być zależne od implementacji ... między innymi.