Przykład:
public class TestClass {
public static void main(String[] args) {
TestClass t = new TestClass();
}
private static void testMethod() {
abstract class TestMethod {
int a;
int b;
int c;
abstract void implementMe();
}
class DummyClass extends TestMethod {
void implementMe() {}
}
DummyClass dummy = new DummyClass();
}
}
Dowiedziałem się, że powyższy fragment kodu jest całkowicie legalny w Javie. Mam następujące pytania.
- Jaki jest pożytek z posiadania definicji klasy wewnątrz metody?
- Czy zostanie wygenerowany plik klasy
DummyClass
- Trudno mi sobie wyobrazić tę koncepcję w sposób obiektowy. Posiadanie definicji klasy wewnątrz zachowania. Prawdopodobnie ktoś może mi powiedzieć na podstawie równoważnych przykładów ze świata rzeczywistego.
- Klasy abstrakcyjne wewnątrz metody brzmią dla mnie trochę szalenie. Ale żadne interfejsy nie są dozwolone. Czy jest jakiś powód?
java
class
local-class
przechwałek
źródło
źródło
Odpowiedzi:
Nazywa się to klasą lokalną.
2 jest łatwy: tak, zostanie wygenerowany plik klasy.
1 i 3 to w pewnym sensie to samo pytanie. Użyłbyś klasy lokalnej, w której nigdy nie musisz tworzyć instancji ani wiedzieć o szczegółach implementacji gdziekolwiek, ale w jednej metodzie.
Typowym zastosowaniem byłoby utworzenie jednorazowej implementacji jakiegoś interfejsu. Na przykład często zobaczysz coś takiego:
Jeśli potrzebujesz utworzyć kilka z nich i coś z nimi zrobić, możesz zmienić to na
Odnośnie interfejsów: nie jestem pewien, czy istnieje problem techniczny, który sprawia, że interfejsy zdefiniowane lokalnie są problemem dla kompilatora, ale nawet jeśli nie ma, nie dodają żadnej wartości. Gdyby klasa lokalna implementująca interfejs lokalny była używana poza metodą, interfejs byłby bez znaczenia. A gdyby klasa lokalna miała być używana tylko wewnątrz metody, zarówno interfejs, jak i klasa zostałyby zaimplementowane w tej metodzie, więc definicja interfejsu byłaby zbędna.
źródło
parameter
powyższe może być zadeklarowane w metodzie otaczającej i jest dostępne dla obu wątków.Nazywa się to klasami lokalnymi . Szczegółowe wyjaśnienie i przykład można znaleźć tutaj . Przykład zwraca konkretną implementację, o której nie musimy wiedzieć poza metodą.
źródło
Klasy nie można zobaczyć (tj. Utworzyć instancji, jej metody są dostępne bez odbicia) spoza metody. Może również uzyskać dostęp do zmiennych lokalnych zdefiniowanych w testMethod (), ale przed definicją klasy.
Właściwie pomyślałem: „Żaden taki plik nie zostanie zapisany”. dopóki tego nie wypróbowałem: O tak, taki plik jest tworzony! Nazywa się coś w rodzaju A $ 1B.class, gdzie A to klasa zewnętrzna, a B to klasa lokalna.
Zwłaszcza w przypadku funkcji wywołania zwrotnego (obsługi zdarzeń w GUI, takich jak onClick () po kliknięciu przycisku itp.) Dość często używa się „klas anonimowych” - przede wszystkim dlatego, że można uzyskać ich dużo. Ale czasami klasy anonimowe nie są wystarczająco dobre - zwłaszcza, że nie można na nich zdefiniować konstruktora. W takich przypadkach te metody lokalne klasy mogą być dobrą alternatywą.
źródło
TestClass$1TestMethodClass.class
, analogicznie do tego, jak.class
nazywane są pliki klas wewnętrznych .Prawdziwym celem tego jest umożliwienie nam tworzenia klas wbudowanych w wywołania funkcji, aby pocieszyć tych z nas, którzy lubią udawać, że piszemy w języku funkcjonalnym;)
źródło
Jedynym przypadkiem, w którym chciałbyś mieć pełnowymiarową klasę wewnętrzną funkcji w porównaniu z klasą anonimową (znaną jako zamknięcie Java), jest spełnienie następujących warunków
Np. Ktoś chce,
Runnable
a Ty chcesz zarejestrować, kiedy wykonanie rozpoczęło się i zakończyło.Z klasą anonimową nie jest to możliwe, z klasą wewnętrzną możesz to zrobić.
Oto przykład, który demonstruje mój punkt widzenia
Jednak przed użyciem tego wzorca należy ocenić, czy zwykła stara klasa najwyższego poziomu, klasa wewnętrzna lub statyczna klasa wewnętrzna są lepszą alternatywą.
źródło
Głównym powodem definiowania klas wewnętrznych (w ramach metody lub klasy) jest zajęcie się dostępnością elementów członkowskich i zmiennych otaczającej klasy i metody. Klasa wewnętrzna może wyszukiwać członków prywatnych danych i operować na nich. Jeśli znajduje się w metodzie, może również obsługiwać końcową zmienną lokalną.
Posiadanie klas wewnętrznych pomaga w upewnieniu się, że ta klasa nie jest dostępna dla świata zewnętrznego. Dotyczy to zwłaszcza przypadków programowania interfejsu użytkownika w GWT lub GXT itp., Gdzie kod generujący JS jest napisany w java, a zachowanie dla każdego przycisku lub zdarzenia musi być zdefiniowane przez utworzenie anonimowych klas
źródło
Wiosną trafiłem na dobry przykład. Framework wykorzystuje koncepcję lokalnych definicji klas wewnątrz metody, aby w jednolity sposób radzić sobie z różnymi operacjami na bazie danych.
Załóżmy, że masz taki kod:
Najpierw spójrzmy na implementację execute ():
Zwróć uwagę na ostatnią linię. Spring wykonuje tę samą sztuczkę w przypadku pozostałych metod:
„Sztuczka” z klasami lokalnymi umożliwia platformie radzenie sobie ze wszystkimi scenariuszami w jednej metodzie, która akceptuje te klasy za pośrednictwem interfejsu StatementCallback. Ta pojedyncza metoda działa jako pomost między akcjami (wykonanie, aktualizacja) i typowymi operacjami wokół nich (np. Wykonywanie, zarządzanie połączeniami, translacja błędów i wyjście konsoli dbms)
źródło