2012-03-24 13 views
29

Dlaczego IDE narzeka na "przeciekanie tego w konstruktorze"? Zawsze zakładałem, że to po prostu zła praktyka. Ale tak naprawdę nigdy nie odkryłem, dlaczego jest źle.Wyciek Java to w konstruktorze

+0

Spójrz na http://stackoverflow.com/questions/3921616/java-leaking-this-in-constructor –

+0

FWIW, w rzeczywistości istnieje teoretyczna luka bezpieczeństwa JVM, jeśli "to" wyciekło bardzo wcześnie w konstruktorze . Ale JVM (podobno) zapewnia, że ​​nie możesz przeciekać tego wcześniej. –

Odpowiedz

56

Wyciek odniesienia w konstruktora (nie Controller) this jest niebezpieczne, zwłaszcza w środowisku wielowątkowym. Dzieje się tak dlatego, że obiekt nie jest w pełni skonstruowany, dopóki nie zakończy się wywołanie konstruktora. Wycieknięcie z konstruktora this oznacza, że ​​świat zewnętrzny uzyskuje dostęp do obiektu, który nie jest jeszcze w pełni skonstruowany. To niekoniecznie prowadzi do problemów w programie jednowątkowym (choć jest to możliwe, ale problem jest w tym przypadku bardziej oczywisty). Ale jeśli this wycieknie do innych wątków, mogą faktycznie spróbować zrobić coś z obiektem przed jego ukończeniem, co prowadzi do subtelnych i trudnych do znalezienia błędów.

+2

Czy ktoś mógłby proszę utworzyć i dołączyć do tego posta "najlepszą praktykę"? – user1050755

+2

Jaki byłby przykład problemu z wyciekiem "tego" w programie z jednym gwintem? – WaelJ

7

W życiu jest kilka absolutów, np. musisz płacić podatki ... lub ... śmierć jest nieunikniona. Ale "przekazanie this z konstruktora jest zawsze złe" - nie jest jednym z nich.

Ograniczenia wskazane przez Petera są trafne i ważne. Z pewnością problematyczne byłoby przecięcie this z konstruktora w dowolną metodę lub kontekst, w którym odniesienie zostanie opublikowane dla nieznanych lub niezaufanych klientów. Niedobrze jest opublikować referencję dla jeszcze nie w pełni skonstruowanego obiektu na dowolny kod klienta, zaufany lub nie, który działa przy założeniu, że będzie miał widok na poprawny i spójny obiekt.

Powiedział, że nie ma absolutnie nic złego w przejściu this od konstruktora sposobu opakowania-prywatnego, który wykonuje wspólne inicjowanie na, powiedzmy, grupy obiektów, które mają wspólny interfejs, szczególnie jeśli inicjalizacja jest długa lub złożony.

TL; DR: Z pewnością istnieją sytuacje, w których, moim zdaniem, nie jest dopuszczalne zaakceptowanie tylko this od konstruktora, ale jest to naprawdę pożądane.

+6

Po prostu tego nie rób. Po prostu marnowaliśmy dni na pracę nad błędem stworzonym wiele lat temu, kiedy ktoś przekazał "to" z konstruktora do "zaufanej" metody "prywatnej paczki". Z biegiem czasu metoda ta narastała, a niezainicjowana instancja dostała się do kolejki zdarzeń. Po prostu użyj ostatecznego init() po zbudowaniu i zostań anonimowym bohaterem. – Charlweed