Przykładowy samouczek dotyczący metod ogólnych języka Java – metoda ogólna, klasa, interfejs
Java Genrics to jedna z najważniejszych funkcji wprowadzonych w Javie 5.
Jeśli pracowałeś nad kolekcjami Java i wersją 5 lub wyższą, jestem pewien, że z niej korzystałeś.
Typy generyczne w Javie z klasami kolekcji są bardzo łatwe, ale zapewniają o wiele więcej funkcji niż tylko tworzenie rodzaj zbioru.
W tym artykule postaramy się poznać cechy typów ogólnych. Zrozumienie typów ogólnych może czasami być mylące, jeśli używamy żargonowych słów, dlatego postaram się, aby było to proste i łatwe do zrozumienia.
Generics w Javie
Generics został dodany w Javie 5, aby zapewnić sprawdzanie typu w czasie kompilacji i usuwanie ryzyka ClassCastException
, które było częste podczas pracy z klasami kolekcji. Cała struktura kolekcji została ponownie napisana, aby używać typów ogólnych w celu zapewnienia bezpieczeństwa typów. Zobaczmy, jak typy ogólne pomagają nam bezpiecznie używać klas kolekcji.
Powyższy kod dobrze się kompiluje, ale w czasie wykonywania generuje wyjątek ClassCastException, ponieważ próbujemy rzutować obiekt z listy na ciąg, podczas gdy jeden z elementów jest typu Integer. Po Javie 5 używamy klas kolekcji, takich jak poniżej.
Zauważ, że podczas tworzenia listy określiliśmy, że typem elementów na liście będzie String. Jeśli więc spróbujemy dodać inny typ obiektu do listy, program zgłosi błąd kompilacji. Zauważ również, że w pętli for nie potrzebujemy rzutowania elementów na listę, dlatego usuwamy wyjątek ClassCastException w czasie wykonywania.
Klasa generyczna Java
Możemy zdefiniować własne klasy z typem generycznym. Typ ogólny to klasa lub interfejs, który jest sparametryzowany dla typów. Używamy nawiasów kątowych (< >) do określenia parametru typu.
Aby zrozumieć korzyści, powiedzmy mamy prostą klasę, taką jak:
Zauważ, że używając tej klasy, musimy użyć rzutowania typów i może ona wygenerować ClassCastException w czasie wykonywania. Teraz użyjemy klasy generycznej java do przepisania tej samej klasy, jak pokazano poniżej.
Zwróć uwagę na użycie klasy GenericsType w metodzie main. Nie musimy rzucać typów i możemy usunąć ClassCastException w czasie wykonywania. Jeśli nie podamy typu w momencie tworzenia, kompilator wyświetli ostrzeżenie, że „GenericsType jest typem surowym.
Odniesienia do typu ogólnego GenericsType < T > powinien być sparametryzowany ”. Gdy nie podamy typu, typem staje się Object
, a zatem dopuszcza zarówno ciąg znaków i obiektów typu Integer. Zawsze jednak powinniśmy starać się tego unikać, ponieważ będziemy musieli używać rzutowania typów podczas pracy z typami surowymi, które mogą powodować błędy w czasie wykonywania.
@SuppressWarnings("rawtypes")
adnotacja, aby pominąć ostrzeżenie kompilatora, zapoznaj się z samouczkiem dotyczącym adnotacji w języku Java. Zauważ również, że obsługuje on autoboxing java.
Ogólny interfejs Java
Porównywalny interfejs jest doskonałym przykładem Generics w interfejsach i jest zapisany jako:
W podobny sposób możemy tworzyć ogólne interfejsy w javie. Możemy również mają wiele parametrów typu, jak w interfejsie Map zysk możemy również podać sparametryzowaną wartość do sparametryzowanego typu, na przykład new HashMap<String, List<String>>();
jest poprawne.
Generic Type Java
Java Generic Type Naming Konwencja pomaga nam łatwo zrozumieć kod, a posiadanie konwencji nazewnictwa jest jedną z najlepszych praktyk języka programowania Java. Tak więc typy generyczne mają również własne konwencje nazewnictwa. Zwykle nazwy parametrów typu składają się z pojedynczych, dużych liter, aby można je było łatwo odróżnić od zmiennych Java. Najczęściej używanymi nazwami parametrów typu są:
- E – Element (używane szeroko w środowisku Java Collections Framework, na przykład ArrayList, Set itp.)
- K – Key ( Używany w mapie)
- N – liczba
- T – typ
- V – wartość (używana w mapie)
- S, U, V itd. – 2, 3, 4 typy
Metoda ogólna Java
Czasami nie chcemy, aby cała klasa była sparametryzowana, w takim przypadku możemy utwórz metodę generyczną java. Ponieważ konstruktor jest specjalnym rodzajem metody, możemy również używać typów ogólnych w konstruktorach.
Oto klasa pokazująca przykład ogólnej metody Java.
Zwróć uwagę na metodę isEqual sygnatura pokazująca składnię do używania typu generycznego w metodach. Zwróć także uwagę, jak używać tych metod w naszym programie java. Możemy określić typ podczas wywoływania tych metod lub możemy je wywołać jak normalną metodę. Kompilator Java jest wystarczająco inteligentny, aby określić typ zmiennej, która ma zostać użyta, ta funkcja nazywa się wnioskiem o typie.
Java Generics Bounded Type Parameters
Załóżmy, że chcemy ograniczyć typ obiektów, które mogą być użyte w parametryzowanym typie, na przykład w metodzie, która porównuje dwa obiekty i chcemy upewnij się, że akceptowane obiekty są porównywalne. Aby zadeklarować parametr typu ograniczonego, należy podać nazwę parametru typu, a następnie słowo kluczowe extends, a następnie górną granicę, podobnie jak w poniższej metodzie.
wywołanie tych metod jest podobne do metody nieograniczonej, z tym wyjątkiem, że jeśli spróbujemy użyć dowolnej klasy, która nie jest porównywalna, spowoduje to zgłoszenie błędu w czasie kompilacji.
Ograniczone parametry typu mogą być używane zarówno z metodami, jak i klasy i interfejsy.
Java Generics obsługuje również wiele granic, tj. < T extends A & B & C >. W tym przypadku A może być interfejsem lub klasą. Jeśli A jest klasą, to B i C powinny być interfejsami. Nie możemy mieć więcej niż jednej klasy w wielu granicach.
Java Generics and Inheritance
Wiemy, że Dziedziczenie w Javie pozwala nam przypisać zmienną A do innej zmiennej B, jeśli A jest podklasą B. Moglibyśmy więc pomyśleć, że dowolny typ ogólny A można przypisać do typu ogólnego B, ale tak nie jest. Zobaczmy to w prostym programie.
Nie możemy przypisać zmiennej MyClass < String > zmiennej MyClass < Obiekt > zmienne, ponieważ nie są one powiązane, w rzeczywistości MyClass < T > rodzicem jest Object.
Ogólne klasy i podtypy Java
Możemy podtypować klasę ogólną lub interfejs, rozszerzając go lub implementując. Relacja między parametrami typu jednej klasy lub interfejsu a parametrami typu innej jest określana przez klauzule extends i implements.
Relacja podtypów jest zachowana, o ile nie zmienimy argumentu type, poniżej przedstawiono przykład wielu parametrów typu.
Podtypy listy < String > może być MyList < String, Object >, MyList < String, Integer > itd.
Java Generics Wildcards
Znak zapytania (?) To symbol wieloznaczny w typach ogólnych i reprezentuje nieznany typ. Symbol wieloznaczny może być używany jako typ parametru, pola lub zmiennej lokalnej, a czasem jako typ zwracany. Nie możemy używać symboli wieloznacznych podczas wywoływania metody ogólnej lub tworzenia instancji klasy ogólnej. W kolejnych sekcjach dowiemy się o znakach wieloznacznych z górną granicą, z dolnymi ograniczeniami i przechwytywaniu symboli wieloznacznych.
9.1) Java Generics Upper Bounded Wildcard
Górne symbole wieloznaczne służą do złagodzenia ograniczenie typu zmiennej w metodzie. Załóżmy, że chcemy napisać metodę, która zwróci sumę liczb na liście, więc nasza implementacja będzie wyglądać mniej więcej tak.
Teraz problem z powyższa implementacja jest taka, że nie będzie działać z listą liczb całkowitych ani podwójnych, ponieważ wiemy, że lista < Integer > i lista < Podwójne > nie są powiązane, to jest wtedy, gdy pomocny jest symbol wieloznaczny z górną granicą. Używamy symboli wieloznacznych generics ze słowem kluczowym extends i górną granicą klasy lub interfejsu, które pozwolą nam przekazać argument z górnej granicy lub typów jej podklas.
Powyższa implementacja może być zmodyfikowana jak poniższy program.
Podobnie jest z pisaniem naszego kodu w zakresie interfejsu, w powyższej metodzie możemy użyć wszystkich metod z górnej granicy klasy Number. Zauważ, że w przypadku listy ograniczonej górą nie możemy dodawać do listy żadnego obiektu poza null. Jeśli spróbujemy dodać element do listy wewnątrz metody sum, program się nie skompiluje.
9.2) Java Generics Unbounded Wildcard
Czasami mamy sytuację, w której chcemy, aby nasza ogólna metoda działała ze wszystkimi typami, w tym przypadku można użyć nieograniczonego symbolu wieloznacznego. To to samo, co użycie <? extends Object >.
Możemy dostarczyć Listę < Ciąg > lub Lista < Integer > lub inny typ argumentu Lista obiektów do printData, metoda. Podobnie jak w przypadku listy z górną granicą, nie możemy niczego dodawać do listy.
9.3) Java Generics Dolny symbol wieloznaczny
Załóżmy, że chcemy dodać liczby całkowite do listy liczb całkowitych w metodzie, możemy zachować typ argumentu jako List < Integer >, ale będzie powiązany z liczbami całkowitymi, podczas gdy Lista < Liczba > i Lista < Obiekt > może również przechowywać liczby całkowite, więc w tym celu możemy użyć dolnego limitu symbolu wieloznacznego. Aby to osiągnąć, używamy generycznych symboli wieloznacznych (?) Ze słowem kluczowym super i klasą z dolną granicą.
Możemy przekazać dolną granicę lub dowolny nadtyp dolnej granicy jako argument, w tym przypadku kompilator java pozwala powiązane typy obiektów z listą.
Podtypy przy użyciu ogólnych symboli wieloznacznych
Java Generics Type Erasure
Typy ogólne w Java została dodana, aby zapewnić sprawdzanie typów w czasie kompilacji i nie ma ona zastosowania w czasie wykonywania, więc kompilator java używa funkcji wymazywania typów, aby usunąć cały kod sprawdzający typ ogólny w kodzie bajtowym i wstawić rzutowanie typów, jeśli to konieczne. Usunięcie typu zapewnia, że dla typów sparametryzowanych nie zostaną utworzone żadne nowe klasy; w konsekwencji generyczne nie powodują narzutu czasu wykonania.
Na przykład, jeśli mamy klasę ogólną, taką jak poniżej;
Kompilator Java zastępuje parametr typu ograniczonego T pierwszym powiązanym interfejsem, Porównywalny , jak poniżej:
Często zadawane pytania dotyczące typów ogólnych
12.1) Dlaczego używamy typów ogólnych w Javie?
Typy generyczne zapewniają silne sprawdzanie typów w czasie kompilacji i zmniejszają ryzyko ClassCastException i jawne rzutowanie obiektów.
12.2) Co to jest T w typowych?
Używamy < T >, aby utworzyć klasę ogólną, interfejs i metodę. T jest zastępowany przez rzeczywisty typ, kiedy go używamy.
12.3) Jak Generics działa w Javie?
Kod ogólny zapewnia bezpieczeństwo typów. Kompilator używa type-erasure, aby usunąć wszystkie parametry typu w czasie kompilacji, aby zmniejszyć przeciążenie w czasie wykonywania.
Typy ogólne w Javie – dalsze informacje
To wszystko dla typów ogólnych w java, java leki generyczne to naprawdę obszerny temat, którego zrozumienie i efektywne wykorzystanie zajmuje dużo czasu. Ten post jest próbą przedstawienia podstawowych informacji o typach generycznych i jak możemy go użyć do rozszerzenia naszego programu o bezpieczeństwo typów.