Do czego służą anonimowe klasy w Javie? Czy możemy powiedzieć, że korzystanie z anonimowej klasy jest jedną z zalet Javy?
java
anonymous-class
anonymous-inner-class
Wojownik
źródło
źródło
Odpowiedzi:
Przez „anonimową klasę” rozumiem, że masz na myśli anonimową klasę wewnętrzną .
Anonimowa klasa wewnętrzna może się przydać, gdy tworzy się instancję obiektu z pewnymi „dodatkami”, takimi jak metody przesłonięcia, bez konieczności faktycznej podklasy klasy.
Zwykle używam go jako skrótu do dołączania detektora zdarzeń:
Zastosowanie tej metody sprawia, że kodowanie jest trochę szybsze, ponieważ nie muszę tworzyć dodatkowej klasy, która się implementuje
ActionListener
- mogę po prostu utworzyć anonimową klasę wewnętrzną bez tworzenia osobnej klasy.Używam tej techniki tylko do zadań „szybkich i brudnych”, w których tworzenie całej klasy wydaje się niepotrzebne. Posiadanie wielu anonimowych klas wewnętrznych, które robią dokładnie to samo, należy przekształcić w klasę rzeczywistą, czy to klasę wewnętrzną, czy osobną.
źródło
overloading methods
a nieoverriding methods
?Anonimowe klasy wewnętrzne są skutecznie zamknięciami, więc można ich używać do emulacji wyrażeń lambda lub „delegatów”. Na przykład weź ten interfejs:
Możesz użyć tego anonimowo, aby stworzyć pierwszorzędną funkcję w Javie. Załóżmy, że masz następującą metodę, która zwraca pierwszą liczbę większą niż i na podanej liście lub i, jeśli żadna liczba nie jest większa:
A następnie masz inną metodę, która zwraca pierwszą liczbę mniejszą niż i na podanej liście lub i, jeśli żadna liczba nie jest mniejsza:
Te metody są prawie identyczne. Używając funkcji pierwszej klasy typu F, możemy przepisać je na jedną z metod w następujący sposób:
Możesz użyć anonimowej klasy, aby użyć metody firstMatch:
To naprawdę wymyślony przykład, ale łatwo zauważyć, że możliwość przekazywania funkcji tak, jakby były wartościami, jest dość przydatną funkcją. Zobacz „Czy Twój język programowania może to zrobić” autorstwa samego Joela.
Ładna biblioteka do programowania Java w tym stylu: funkcjonalna Java.
źródło
Anonimowa klasa wewnętrzna jest używana w następującym scenariuszu:
1.) W przypadku przesłonięcia (podklasy), gdy definicja klasy nie jest użyteczna z wyjątkiem bieżącego przypadku:
2.) W przypadku implementacji interfejsu, gdy implementacja interfejsu jest wymagana tylko w bieżącym przypadku:
3.) Anonimowa klasa wewnętrzna zdefiniowana w argumencie:
źródło
Czasami używam ich jako hacków składniowych do tworzenia instancji Map:
vs
Oszczędza to nadmiarowości przy wykonywaniu wielu instrukcji put. Jednak napotkałem również problemy podczas robienia tego, gdy klasa zewnętrzna musi być serializowana poprzez zdalne sterowanie.
źródło
Są one powszechnie stosowane jako pełna forma oddzwaniania.
Przypuszczam, że można powiedzieć, że są zaletą w porównaniu z ich brakiem i koniecznością tworzenia nazwanej klasy za każdym razem, ale podobne koncepcje są wdrażane znacznie lepiej w innych językach (jako zamknięcia lub bloki)
Oto przykład huśtawki
Mimo że wciąż jest bałaganiarski, jest o wiele lepszy niż zmuszanie cię do zdefiniowania nazwanej klasy dla każdego takiego wyrzucającego słuchacza (chociaż w zależności od sytuacji i ponownego użycia może to być lepsze podejście)
źródło
myButton.addActionListener(e -> { /* do stuff here */})
lubmyButton.addActionListener(stuff)
byłoby terser.Używasz go w sytuacjach, w których musisz utworzyć klasę do określonego celu w innej funkcji, np. Jako słuchacz, jako uruchamialny (w celu odrodzenia wątku) itp.
Chodzi o to, że wywołujesz je z wnętrza kodu funkcji, abyś nigdy nie odwoływał się do nich gdzie indziej, więc nie musisz ich nazywać. Kompilator po prostu je wylicza.
Zasadniczo są one cukrem syntaktycznym i powinny być przenoszone gdzie indziej, gdy rosną.
Nie jestem pewien, czy jest to jedna z zalet Javy, ale jeśli z nich korzystasz (i wszyscy często je wykorzystujemy, niestety), możesz argumentować, że są jedną z nich.
źródło
GuideLines dla anonimowej klasy.
Anonimowa klasa jest deklarowana i inicjowana jednocześnie.
Anonimowa klasa musi rozszerzyć lub zaimplementować jedną lub tylko jedną klasę lub interfejs.
Ponieważ klasa anonimowa nie ma nazwy, można jej użyć tylko raz.
na przykład:
źródło
ref.getClass().newInstance()
.Tak, anonimowe klasy wewnętrzne są zdecydowanie jedną z zalet Javy.
Dzięki anonimowej klasie wewnętrznej masz dostęp do zmiennych końcowych i zmiennych klasy otaczającej, co przydaje się w słuchaczach itp.
Ale główną zaletą jest to, że wewnętrzny kod klasy, który jest (przynajmniej powinien być) ściśle powiązany z otaczającą klasą / metodą / blokiem, ma określony kontekst (otaczająca klasa, metoda i blok).
źródło
Jest to również jeden z przykładów anonimowego typu wewnętrznego używającego wątku
źródło
używam anonimowych obiektów do wywoływania nowych wątków ..
źródło
Klasa wewnętrzna jest związana z wystąpieniem zewnętrznej klasy i są dwa specjalne rodzaje: klasa lokalna i klasa Anonymous . Anonimowa klasa umożliwia nam deklarowanie i tworzenie instancji klasy w tym samym czasie, dzięki czemu kod jest zwięzły. Używamy ich, gdy potrzebujemy lokalnej klasy tylko raz, ponieważ nie mają nazwy.
Rozważ przykład z dokumentu, w którym mamy
Person
klasę:i mamy metodę drukowania członków spełniających kryteria wyszukiwania jako:
gdzie
CheckPerson
jest interfejs taki jak:Teraz możemy skorzystać z anonimowej klasy, która implementuje ten interfejs do określenia kryteriów wyszukiwania jako:
Tutaj interfejs jest bardzo prosty, a składnia anonimowej klasy wydaje się niewygodna i niejasna.
Java 8 wprowadziła termin Interfejs funkcjonalny, który jest interfejsem z tylko jedną metodą abstrakcyjną, dlatego możemy powiedzieć, że
CheckPerson
jest interfejsem funkcjonalnym. Możemy skorzystać z wyrażenia Lambda, które pozwala nam przekazać funkcję jako argument metody jako:Predicate
Zamiast interfejsu możemy użyć standardowego interfejsu funkcjonalnegoCheckPerson
, co dodatkowo zmniejszy ilość wymaganego kodu.źródło
Anonimowa klasa wewnętrzna może być korzystna, dając różne implementacje dla różnych obiektów. Ale należy go używać bardzo oszczędnie, ponieważ stwarza to problemy z czytelnością programu.
źródło
Jednym z głównych zastosowań anonimowych klas w procesie finalizacji klas, który nazywał opiekuna finalizatora . W świecie Java należy unikać stosowania metod finalizacji, dopóki nie będą one naprawdę potrzebne. Musisz pamiętać, że kiedy przesłonisz metodę finalizacji dla podklas, zawsze powinieneś wywoływać
super.finalize()
, ponieważ metoda finalizacji superklasy nie wywoła się automatycznie i możesz mieć problemy z wyciekami pamięci.uwzględniając powyższy fakt, możesz po prostu użyć anonimowych klas, takich jak:
Korzystając z tej techniki, odciążyłeś siebie i innych programistów od wywołania
super.finalize()
każdej podklasy,HeavyClass
która wymaga metody finalizacji.źródło
W ten sposób możesz użyć anonimowej klasy
źródło
Wygląda na to, że nikt tu nie był wymieniony, ale możesz także użyć klasy anonimowej do przechowywania ogólnego argumentu typu (który zwykle traci się z powodu usunięcia typu) :
Jeśli utworzysz tę klasę w sposób anonimowy
to takie
holder
instancja będzie zawierać nieusuniętą definicję przekazywanego typu.Stosowanie
Jest to bardzo przydatne do budowania walidatorów / deserializatorów. Możesz także utworzyć typ ogólny z odbiciem (więc jeśli kiedykolwiek chciałeś zrobić
new T()
w parametryzowanym typie - nie ma za co!) .Wady / ograniczenia
źródło
Najlepszy sposób na optymalizację kodu. możemy również użyć do nadrzędnej metody klasy lub interfejsu.
źródło
Anonymous Klasa wewnętrzna służy do tworzenia obiektu, który nigdy nie zostanie ponownie odwołuje. Nie ma nazwy, jest zadeklarowany i utworzony w tej samej instrukcji. Jest to używane tam, gdzie normalnie użyłbyś zmiennej obiektu. Zmienną zamieniasz
new
słowo kluczowe, wywołanie konstruktora i definicję klasy wewnątrz{
i}
.Podczas pisania programu wątkowego w Javie zwykle wyglądałby tak
ThreadClass
Stosowane tutaj byłoby zdefiniowane przez użytkownika. Ta klasa zaimplementujeRunnable
interfejs wymagany do tworzenia wątków. W (metoda tylko w ) musi zostać wdrożony, jak również. Oczywiste jest, że się go pozbyćThreadClass
run()
Runnable
ThreadClass
byłoby bardziej wydajne i właśnie dlatego istnieją Anonimowe Klasy Wewnętrzne.Spójrz na następujący kod
Ten kod zastępuje odniesienie do
task
najbardziej znanego przykładu. Zamiast mieć osobną klasę, Anonimowa Klasa Wewnętrzna wewnątrzThread()
konstruktora zwraca nienazwany obiekt, który implementujeRunnable
interfejs i zastępujerun()
metodę. Metodarun()
obejmowałaby wewnątrz instrukcje, które wykonują pracę wymaganą przez wątek.Odpowiadając na pytanie, czy Anonimowe Klasy Wewnętrzne są jedną z zalet Javy, muszę powiedzieć, że nie jestem do końca pewien, ponieważ nie znam obecnie wielu języków programowania. Ale mogę powiedzieć, że jest to zdecydowanie szybsza i łatwiejsza metoda kodowania.
Referencje: Sams Teach Your Jav Java in 21 Days Seventh Edition
źródło
Jeszcze jedna zaleta:
ponieważ wiesz, że Java nie obsługuje wielokrotnego dziedziczenia, więc jeśli użyjesz klasy „Wątek” jako klasy anonimowej, w klasie pozostanie jeszcze jedno miejsce na rozszerzenie dowolnej innej klasy.
źródło