Widziałem tę linię w metodzie klasowej i moją pierwszą reakcją było wyśmiewanie programisty, który ją napisał. Ale potem pomyślałem, że powinienem najpierw upewnić się, że mam rację.
public void dataViewActivated(DataViewEvent e) {
if (this != null)
// Do some work
}
Czy ta linia kiedykolwiek zostanie uznana za fałszywą?
Odpowiedzi:
Nie, nie może. Jeśli używasz
this
, to jesteś w instancji, więcthis
nie jest null.JLS mówi:
Jeśli wywołałeś metodę z obiektu, to obiekt istnieje lub miałbyś
NullPointerException
przed (lub jest to metoda statyczna, ale wtedy nie możeszthis
w niej użyć ).Zasoby :
this
słowo kluczoweźródło
this
metoda instancji może mieć wartość NULL. Więc nie jestem do końca przekonany, że to wystarczający powód w Javie.foo.bar()
zostałby zgłoszony, gdyfoo
zostanie wykrytynull
. dzieje się to przed wejściem do metody, ale prawdziwa historia jest taka, że nie ma metody, którą można by spróbować wywołać.this
słowa kluczowego i kompiluje się, nie jest ono zerowe, gdy je obserwujesz. Ale, jak mówią inni, nie zapobiega to NPE podczas próby wywołania metody, np. Ale to jest całkowicie poza twoją kontrolą jako metoda, a zerowe sprawdzenie w metodzie niczego nie zmieni.To tak, jakbyś zadał sobie pytanie „Czy żyję?”
this
nigdy nie może być zeroweźródło
this != null
było oczywiste. Tak nie jest - na przykład w C ++this
może tak byćNULL
dla metody niewirtualnej.Nie, nigdy , słowo kluczowe „this” samo w sobie reprezentuje bieżącą aktywną instancję (obiekt) tej klasy w zakresie tej klasy, za pomocą której można uzyskać dostęp do wszystkich jej pól i składowych (w tym konstruktorów) oraz widocznych z jej klasy nadrzędnej.
Co ciekawsze, spróbuj ustawić to:
Pomyśl o tym? Jak to możliwe, czy nie będzie to jak przecinanie gałęzi, na której siedzisz. Ponieważ słowo kluczowe „this” jest dostępne w zakresie klasy, więc gdy tylko powiesz this = null; gdziekolwiek w klasie to po prostu prosisz JVM o zwolnienie pamięci przypisanej do tego obiektu w trakcie jakiejś operacji, na którą JVM po prostu nie może pozwolić, ponieważ musi bezpiecznie wrócić po zakończeniu tej operacji.
Co więcej, próbując
this = null;
zakończy się błędem kompilatora. Przyczyna jest dość prosta, słowu kluczowemu w Javie (lub jakimkolwiek innym języku) nie można nigdy przypisać wartości, tj. Słowo kluczowe nigdy nie może być lewą wartością operacji przypisania.Inne przykłady, których nie możesz powiedzieć:
źródło
this = null
. Moja instancja była w systemie Android, gdzie chciałem usunąć widok i ustawić obiekt obsługujący widok na null. Następnie chciałem użyć metody,remove()
która usunęłaby rzeczywisty widok, a następnie obiekt obsługi stałby się bezużyteczny, więc chciałem go wyzerować.Jeśli kompilujesz z
-target 1.3
lub wcześniej, może to być plik zewnętrzny . A przynajmniej kiedyś ...this
null
źródło
Outer.this.member
Nie. Aby wywołać metodę instancji klasy, instancja musi istnieć. Wystąpienie jest niejawnie przekazywane jako parametr do metody, do której odwołuje się
this
. Gdyby takthis
było,null
nie byłoby instancji do wywołania metody.źródło
Nie wystarczy, że język to wymusza. Maszyna wirtualna musi to wymusić. O ile maszyna wirtualna tego nie wymusza, można napisać kompilator, który nie wymusza sprawdzenia wartości null przed wywołaniem metody napisanej w języku Java. Kody operacyjne dla wywołania metody instancji obejmują ładowanie tego odniesienia na stos, patrz: http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14787 . Zastąpienie tego pustym odniesieniem rzeczywiście spowodowałoby, że test byłby fałszywy
źródło
W statycznych metodach klas
this
nie jest zdefiniowany, ponieważthis
jest powiązany z instancjami, a nie z klasami. Uważam, że próba użyciathis
słowa kluczowego w kontekście statycznym spowodowałaby błąd kompilatora .źródło
Normalny
this
nigdy nie może byćnull
w prawdziwym kodzie Java 1 , a Twój przykład używa normalnegothis
. 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:Kiedy chcemy utworzyć instancję
Inner
, musimy to zrobić:Wynik to:
pokazując, że nasza próba stworzenia
Inner
znull
odniesieniem do ichOuter
zawiódł.W rzeczywistości, jeśli trzymasz się obwiedni „czystej Javy”, nie możesz tego złamać.
Jednak każda
Inner
instancja ma ukrytefinal
pole 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ćnull
do pola.Unsafe
zrobić.Tak czy inaczej, efekt końcowy jest taki, że
Outer.this
wyrażenie wyniesienull
2 .W skrócie, jest to możliwe dla wykwalifikowanego
this
być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.
źródło
Gdy wywołasz metodę w
null
odwołaniu,NullPointerException
zostanie ona wyrzucona z maszyny wirtualnej Java. Dzieje się tak według specyfikacji, więc jeśli maszyna wirtualna Java jest ściśle zgodna ze specyfikacją,this
nigdy by tak nie byłonull
.źródło
Jeśli metoda jest statyczna, nie ma żadnej
this
. Jeśli metoda jest wirtualna,this
nie może mieć wartości null, ponieważ w celu wywołania metody środowisko wykonawcze będzie musiało odwołać się do tabeli vtable za pomocąthis
wskaźnika. Jeśli metoda nie jest wirtualna , to tak, możliwe, żethis
jest zerowa.C # i C ++ zezwalają na metody niewirtualne, ale w Javie wszystkie metody niestatyczne są wirtualne, więc
this
nigdy nie będą miały wartości NULL.źródło
tl; dr, "this" można wywołać tylko z metody niestatycznej i wszyscy wiemy, że metoda niestatyczna jest wywoływana z jakiegoś obiektu, który nie może mieć wartości NULL.
źródło