Czy używanie przestarzałych metod lub klas w Javie jest złe?

153

Używam eclipse do tworzenia aplikacji internetowych. Właśnie dzisiaj zaktualizowałem moją wersję kolumny, zmieniając plik JAR. W niektórych miejscach pojawiają się ostrzeżenia, że ​​metody są przestarzałe, ale kod działa poprawnie.

Chcę wiedzieć kilka rzeczy

  1. Czy używanie przestarzałych metod lub klas w Javie jest złe?

  2. Co się stanie, jeśli nie zmienię żadnej metody i uruchomię aplikację z ostrzeżeniami, czy spowoduje to jakiekolwiek problemy z wydajnością.

Umesh Aawte
źródło
7
Czy `` kontynuowałbyś '' jazdę swoim samochodem, 1955 Volkswagen Beetlenawet jeśli zostaniesz zaoferowany Corvette Stingray, za darmo? (0:
KMån
75
@KMan porównujesz samochód europejski do samochodu amerykańskiego ?;)
ponzao
2
@Ponzao i 4inni: Gotcha! (0;
KMån
2
Źle? Czy mówimy tutaj o śmiertelnym czy tylko powszednim pozbawieniu wolności?
FastAl
5
@Alexander nie głosuje na Twój komentarz, więc +1 również dla Ciebie;) W każdym razie, trudno, żeby nowy kod był 1000 lepszy od starego. Porównanie byłoby lepsze od 1955 Volkswagen Beetlei 1956 Volkswagen Beetlenowymi oponami, że nie wiem, kiedy złamie!
Aleks,

Odpowiedzi:

265

1. Czy używanie przestarzałych metod lub klas w Javie jest złe?

Z definicji przestarzałe :

Element programu z adnotacją @Deprecated to taki, którego programiści nie powinni używać, zwykle dlatego, że jest niebezpieczny lub ponieważ istnieje lepsza alternatywa.

Metoda jest przechowywana w interfejsie API w celu zapewnienia zgodności z poprzednimi wersjami przez nieokreślony czas i może zostać usunięta w przyszłych wersjach. To znaczy nie, to nie jest złe , ale istnieje lepszy sposób na zrobienie tego, który jest bardziej odporny na zmiany w API.

2. Co się stanie, jeśli nie zmienię żadnej metody i uruchomię aplikację z ostrzeżeniami, czy spowoduje to jakiekolwiek problemy z wydajnością.

Najprawdopodobniej nie. Będzie nadal działać tak, jak przed wycofaniem. Umowa metody API nie ulegnie zmianie. Jeśli jakaś wewnętrzna struktura danych zmieni się na korzyść nowej, lepszej metody, może to mieć wpływ na wydajność, ale jest to mało prawdopodobne.


Deprecation najśmieszniejsze w Java API, to IMO FontMetrics.getMaxDecent. Przyczyna wycofania: błąd ortograficzny.

Przestarzałe. Od wersji JDK 1.1.1 zastąpione przez getMaxDescent ().

aioobe
źródło
5
Kolejnym najzabawniejszym wycofaniem w Java API byłoby setMultiClickThreshhold (int threshhold) i getMultiClickTreshhold () w AbstractButton (Swing). Przygotuj się na tych dwoje! ;)
JavaTechnical
3
Musimy to zrobić za pomocą HTTP REFERER. To irytujące: en.wikipedia.org/wiki/HTTP_referer
kmiklas
1
@DaveMcClelland, zrobiłem to 70 z 69: D;)
VdeX
28

Nadal możesz używać przestarzałego kodu bez zmiany wydajności, ale głównym celem wycofania metody / klasy jest poinformowanie użytkowników, że teraz jest lepszy sposób na ich użycie i że w przyszłej wersji przestarzały kod prawdopodobnie zostanie usunięty.

otchłań
źródło
1
Skąd możesz mieć pewność, że nie zmieni to wydajności? Pozbawienie praw może na przykład wynikać ze zmiany wewnętrznej struktury danych, na przykład z zestawu HashSet na zestaw TreeSet.
aioobe
@aioobe - zgodnie z moim zrozumieniem, OP zapytał, czy wywołanie przestarzałego kodu ma jakiekolwiek problemy z wydajnością, co nie oznacza, że ​​nie zmienia to wyprodukowanego kodu bajtowego (przed 1.5 było w javadoc, teraz adnotacja jest używana, ale nadal bez zmian w wydajności)
abyx
Podczas przechodzenia z jednej wersji biblioteki do innej nie ma gwarancji, że kod bajtowy metody w nowej wersji jest identyczny z kodem bajtowym tej samej metody w poprzedniej wersji.
aioobe
@aioobe - istnieje gwarancja, że ​​po prostu wycofanie go nie zmieni kodu bajtowego, co moim zdaniem oznaczał OP. Oczywiście sam kod się zmienia, dlatego wycofujemy kod.
abyx
Jeśli nadal będziesz używać tej samej wersji co poprzednio, nic się nie zmieni. Ale jeśli użytkownik korzysta z nowszej wersji biblioteki i nie ma wycofanego interfejsu API, MOŻE nastąpić zmiana w wydajności, jeśli podstawowa implementacja zostanie drastycznie zmieniona i nowy interfejs API to wykorzysta, podczas gdy starszy interfejs API nie jest tak skuteczny jak kiedyś, w porównaniu z nowszą strukturą.
gregturn
21

Terminologia

Z oficjalnego słownika Sun:

przestarzałe : Odnosi się do klasy, interfejsu, konstruktora, metody lub pola, które nie są już zalecane i mogą przestać istnieć w przyszłej wersji.

Z przewodnika „jak i kiedy wycofać”:

Być może słyszałeś termin „humor samodeprecjonujący” lub humor, który minimalizuje znaczenie mówiącego. Taka jest przestarzała klasa lub metoda. To już nie jest ważne. W rzeczywistości jest to tak nieważne, że nie należy go już używać, ponieważ został on zastąpiony i może przestać istnieć w przyszłości.

@DeprecatedAdnotacja poszedł o krok dalej i ostrzegają o niebezpieczeństwie:

Element programu z adnotacją @Deprecatedto taki, którego programiści nie powinni używać, zwykle dlatego, że jest niebezpieczny lub ponieważ istnieje lepsza alternatywa.

Bibliografia


Prawda czy fałsz?

Kwestię, czy używanie przestarzałych metod jest dobre, czy złe, będzie musiało być rozpatrywane indywidualnie. Oto WSZYSTKIE cudzysłowy, w których słowo „przestarzałe” pojawia się w Effective Java 2nd Edition :

Punkt 7: Unikaj finalizatorów : jedyne metody, które obiecują zagwarantować finalizację, to System.runFinalizersOnExiti jej zły bliźniak Runtime.runFinalizersOnExit. Te metody mają fatalne w skutkach błędy i zostały wycofane.

Punkt 66: Synchronizuj dostęp do udostępnionych danych podlegających zmianom : Biblioteki zapewniają Thread.stopmetodę, ale ta metoda została dawno przestarzała, ponieważ jest z natury niebezpieczna - jej użycie może spowodować uszkodzenie danych.

Punkt 70: Bezpieczeństwo wątków dokumentów : System.runFinalizersOnExitMetoda jest nieprzyjazna dla wątków i została wycofana.

Punkt 73: Unikaj grup wątków : Pozwalają na jednoczesne zastosowanie pewnych Threadprymitywów do kilku wątków. Kilka z tych prymitywów zostało wycofanych, a pozostałe są rzadko używane. [...] grupy wątków są przestarzałe.

Tak więc, przynajmniej w przypadku wszystkich powyższych metod, używanie ich jest ewidentnie niewłaściwe, przynajmniej według Josha Blocha.

W przypadku innych metod należałoby rozważyć te kwestie indywidualnie i zrozumieć, DLACZEGO zostały one wycofane, ale ogólnie rzecz biorąc, gdy decyzja o wycofaniu jest uzasadniona, będzie to raczej skłaniać się ku złemu niż słusznemu dalszemu ich stosowaniu.

Powiązane pytania

smary wielogenowe
źródło
3
„Przestarzały” pochodzi od łacińskiego „de” + „precare”, co oznacza „modlić się przeciwko”. Kiedy coś jest określane jako przestarzałe, Standard modli się - błaga - nie używaj go; to ostrzeżenie, że może zostać usunięty w przyszłej wersji tego standardu. Należy pamiętać, że nieaktualna funkcja musi być w pełni zaimplementowana w każdej implementacji bieżącej wersji tego standardu. Twoja wzmianka o autoironicznym poczuciu humoru jest jednak nieco nie na miejscu; „auto-deprecjonowanie” w tym sensie jest wypaczeniem „samo-deprecjonowania”, które ma inne pochodzenie i znaczenie.
dajames
17

Oprócz wszystkich doskonałych odpowiedzi powyżej, odkryłem, że jest jeszcze jeden powód, aby usunąć przestarzałe wywołania API.

Badając, dlaczego wywołanie jest przestarzałe, często dowiaduję się ciekawych rzeczy o Javie / API / Framework. Często istnieje dobry powód, dla którego metoda jest przestarzała, a zrozumienie tych powodów prowadzi do głębszego wglądu.

Zatem z perspektywy uczenia się / rozwoju jest to również opłacalny wysiłek

Peter Tillemans
źródło
11

Z pewnością nie powoduje to problemu z wydajnością - przestarzałe oznacza, że ​​w przyszłości prawdopodobnie funkcja nie będzie już częścią biblioteki, więc należy unikać używania jej w nowym kodzie i zmienić stary kod, aby przestać go używać, więc nie napotkasz problemów któregoś dnia, kiedy zaktualizujesz kolumny i stwierdzisz, że ta funkcja już nie jest dostępna

Michał Mrozek
źródło
1
Sądząc z doświadczenia, „przestarzałe” tak naprawdę oznacza „nie powinieneś już tego używać, ale będzie ono dostępne na zawsze”. Przynajmniej w przypadku standardowego interfejsu API języka Java nie znam żadnej metody ani klasy, które zostałyby faktycznie usunięte po ich wycofaniu.
Michael Borgwardt
1
@Michael Cóż, w praktyce interfejsy API rzadko usuwają przestarzałe funkcje, ponieważ mogą być przestarzałe przez dziesięć lat, gdy kompilatory wyświetlają komunikat „OSTRZEŻENIE: ZATRZYMAJ UŻYWANIE TEGO GŁUPIA”, a ludzie nadal traciliby ważność w dniu, w którym je ostatecznie usunęli. Myślę, że przestarzałe ma oznaczać "kiedyś będziemy chcieli to usunąć, więc proszę przestańcie z tego korzystać", nawet jeśli w praktyce rzadko się to zdarza
Michael Mrozek
@Michael Mrozek: Nie zgadzam się ze stwierdzeniem It certainly doesn't create a performance issue; jest to zbyt subiektywne, aby to stwierdzić.
KMån
1
@KMan Oznaczenie funkcji jako przestarzałe nie czyni jej mniej wydajną niż przed oznaczeniem - będzie działać dokładnie tak samo jak poprzednio
Michael Mrozek
@Michael Borgwardt: Tak to działa w większości standardowych języków. I oczywiście, gdyby cokolwiek przestarzałego miało zostać usunięte ze standardu, popularne implementacje zachowałyby to jako rozszerzenie.
David Thornley,
8

To nie jest złe, po prostu nie jest zalecane. Ogólnie oznacza to, że w tym momencie istnieje lepszy sposób robienia rzeczy i dobrze by było, gdybyś użył nowego ulepszonego sposobu. Niektóre przestarzałe rzeczy są naprawdę niebezpieczne i należy ich całkowicie unikać. Nowy sposób może zapewnić lepszą wydajność niż wycofany, ale nie zawsze tak jest.

Bozhidar Batsov
źródło
8

Być może słyszałeś termin „samodeprecjonujący humor”. To jest humor, który minimalizuje twoje znaczenie. Taka jest przestarzała klasa lub metoda. To już nie jest ważne. W rzeczywistości jest to tak nieważne, że w ogóle nie powinno się go używać, ponieważ prawdopodobnie przestanie istnieć w przyszłości.

Staraj się tego unikać

Jigar Joshi
źródło
4
  1. Generalnie nie, nie jest absolutnie złe używanie deprecatedmetod, o ile masz dobry plan awaryjny, aby uniknąć problemów, jeśli / kiedy te metody znikną z biblioteki, której używasz. Z samym API Java to się nigdy nie zdarza, ale w przypadku prawie wszystkiego innego oznacza to, że zostanie ono usunięte. Jeśli konkretnie planujesz nie aktualizować ( chociaż najprawdopodobniej powinieneś na dłuższą metę ) bibliotek obsługujących oprogramowanie, nie ma problemu z używaniem deprecatedmetod.
  2. Nie.
Esko
źródło
3

Tak, to źle.

Przestarzałe metody lub klasy zostaną usunięte w przyszłych wersjach języka Java i nie powinny być używane. W każdym przypadku powinna być dostępna alternatywa. Użyć tego.

Istnieje kilka przypadków, w których musisz użyć przestarzałej klasy lub metody, aby osiągnąć cel projektu. W takim przypadku naprawdę nie masz innego wyjścia, jak tylko z niego skorzystać. Przyszłe wersje Javy mogą złamać ten kod, ale jeśli jest to wymagane, musisz z tym żyć. Prawdopodobnie nie jest to pierwszy raz, kiedy musiałeś zrobić coś złego, aby spełnić wymagania projektu, iz pewnością nie ostatni.

Podczas aktualizacji do nowej wersji języka Java lub innej biblioteki czasami używana metoda lub klasa staje się przestarzała. Przestarzałe metody nie są obsługiwane, ale nie powinny dawać nieoczekiwanych wyników. Nie oznacza to jednak, że tak się nie stanie, więc jak najszybciej zmień kod.

Proces wycofywania ma na celu upewnienie się, że autorzy mają wystarczająco dużo czasu na zmianę swojego kodu ze starego interfejsu API na nowy. Wykorzystaj ten czas. Zmień swój kod jak najszybciej.

Erick Robertson
źródło
2

Nie jest źle, ale niektóre z przestarzałych metod zostaną usunięte w przyszłych wersjach oprogramowania, więc prawdopodobnie kod nie będzie działał.

Petar Minchev
źródło
Removed? Zobacz definicję stackoverflow.com/questions/2941900/…
KMån
1
@KMan - w podanym przez Ciebie odsyłaczu jest napisane - „Metoda jest przechowywana w interfejsie API w celu zapewnienia wstecznej kompatybilności przez nieokreślony czas i może zostać USUNIĘTA w przyszłych wersjach”. Napisałem to samo - niektóre z przestarzałych metod zostaną prawdopodobnie usunięte w bliskiej lub dalekiej przyszłości.
Petar Minchev
2

Czy używanie przestarzałych metod lub klas w Javie jest złe? ”

Nie jest źle, ale może zaoszczędzić trochę kłopotów. Oto przykład, w którym zdecydowanie odradza się używanie przestarzałej metody:

http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

Dlaczego Thread.stop jest przestarzały?

Ponieważ jest to z natury niebezpieczne. Zatrzymanie wątku powoduje odblokowanie wszystkich zablokowanych monitorów. (Monitory są odblokowywane, gdy wyjątek ThreadDeath jest propagowany w górę stosu). Jeśli którykolwiek z obiektów wcześniej chronionych przez te monitory był w niespójnym stanie, inne wątki mogą teraz wyświetlać te obiekty w niespójnym stanie. Mówi się, że takie obiekty są uszkodzone. Gdy wątki działają na uszkodzonych obiektach, może to spowodować arbitralne zachowanie. To zachowanie może być subtelne i trudne do wykrycia lub może być wyraźne. W przeciwieństwie do innych niezaznaczonych wyjątków ThreadDeath po cichu zabija wątki; w ten sposób użytkownik nie ma żadnego ostrzeżenia, że ​​jego program może być uszkodzony. Zepsucie może ujawnić się w dowolnym momencie po wystąpieniu rzeczywistej szkody, nawet w ciągu godzin lub dni w przyszłości.


Co jeśli nie zmienisz żadnej metody i uruchomisz moją aplikację z ostrzeżeniami, które mam, czy spowoduje to problem z wydajnością.

Nie powinno być problemów z wydajnością. Standardowy interfejs API został zaprojektowany z zachowaniem pewnej kompatybilności wstecznej, dzięki czemu aplikacje mogą być stopniowo dostosowywane do nowszych wersji języka Java.

James P.
źródło
2

Czy używanie przestarzałych metod lub klas w Javie jest złe? To nie jest „złe”, nadal działa, ale unikaj tego tak bardzo, jak to możliwe.

Załóżmy, że z metodą wiąże się luka w zabezpieczeniach, a programiści stwierdzą, że jest to wada projektowa. Mogą więc zdecydować o wycofaniu metody i wprowadzeniu nowego sposobu.

Więc jeśli nadal używasz starej metody, masz zagrożenie. Dlatego pamiętaj o przyczynie wycofania i sprawdź, czy wpłynie to na Ciebie.

co się stanie, jeśli nie zmienisz żadnej metody i uruchomisz moją aplikację z ostrzeżeniami, które mam, czy spowoduje to problem z wydajnością.

Jeśli wycofanie jest spowodowane problemem z wydajnością, wystąpią problemy z wydajnością, w przeciwnym razie nie ma powodu, aby mieć taki problem. Jeszcze raz chciałbym zwrócić uwagę, pamiętaj o przyczynie wycofania.

Chathuranga Chandrasekara
źródło
2

W Javie jest to @Deprecated, w C # jest to [Obsolete].

Myślę, że wolę terminologię C #. To po prostu oznacza, że ​​jest przestarzały. Nadal możesz go używać, jeśli chcesz, ale prawdopodobnie jest lepszy sposób.

To tak, jakby używać systemu Windows 3.1 zamiast Windows 7, jeśli uważasz, że system Windows 3.1 jest przestarzały. Nadal możesz z niego korzystać, ale prawdopodobnie w przyszłej wersji są lepsze funkcje, a przyszłe wersje prawdopodobnie będą obsługiwane - przestarzała nie będzie.

To samo dotyczy @Deprecated Javy - nadal możesz używać tej metody, ale na własne ryzyko - w przyszłości może ona mieć lepsze alternatywy i może nawet nie być obsługiwana.

Jeśli używasz kodu, który jest przestarzały, zwykle jest w porządku, o ile nie musisz aktualizować interfejsu API do nowszego - przestarzały kod może tam nie istnieć. Proponuję, jeśli zobaczysz coś, co używa przestarzałego kodu, aby zaktualizować go do nowszych alternatyw (zwykle jest to wskazane w adnotacji lub w przestarzałym komentarzu Javadoc).

Edycja: I jak zauważył Michael, jeśli powodem wycofania jest błąd w funkcjonalności (lub ponieważ funkcjonalność nie powinna w ogóle istnieć), to oczywiście nie należy używać przestarzałego kodu.

jamiebarrow
źródło
1
„Jeśli używasz kodu, który jest przestarzały, wszystko jest w porządku, o ile nie musisz aktualizować interfejsu API do nowszego” - niezupełnie. Zobacz, dlaczego Thread.stop () jest przestarzały, a zobaczysz, że nie jest w porządku w żadnej wersji JRE.
Michael
Ok, powinienem raczej powiedzieć „zwykle” dobrze (zaktualizuję ten bit) :) Dlatego używaj na własne ryzyko. Oczywiście, jeśli powodem jego wycofania jest zatrzymanie błędu w jego funkcjonalności, sensowne jest, aby go nie używać. Ogólnie jednak dobrze jest używać przestarzałej metody. Więc ja, wszystko zależy od powodu wycofania. Prawdziwe.
jamiebarrow
1

Oczywiście, że nie - ponieważ cała Java jest @Deprecated :-), możesz używać ich tak długo, jak długo Java będzie działać. I tak nie zauważę żadnej różnicy, chyba że jest to coś naprawdę zepsutego. Znaczenie - przeczytaj o tym, a potem zdecyduj.

Jednak w .Net, gdy coś zostanie uznane za [przestarzałe], idź i przeczytaj o tym natychmiast, nawet jeśli nigdy wcześniej tego nie używałeś - masz około 50% szans, że jest bardziej wydajne i / lub łatwiejsze w użyciu niż wymiana :-))

Ogólnie rzecz biorąc, w dzisiejszych czasach bycie konserwatystą technicznym może być całkiem korzystne, ale najpierw musisz wykonać swoje zadanie czytania.

ZXX
źródło
1

Uważam, że przestarzała metoda oznacza; dostępna jest metoda alternatywna = ive, która jest lepsza pod każdym względem niż dotychczasowa metoda. Lepiej jest użyć dobrej metody niż istniejącej starej metody. W celu zapewnienia zgodności z poprzednimi wersjami stare metody są nieaktualne.

DPM
źródło