Generalizacja Java: opis i metody

Od samego początku języka Java przeszedł wiele zmian, które oczywiście przyniosły pozytywne chwile w jego funkcjonalności. Jedną z takich ważnych zmian jest wprowadzenie Java Generic lub uogólnienie. Ta funkcjonalność sprawiła, że ​​język jest nie tylko bardziej elastyczny i bardziej uniwersalny, ale także znacznie bezpieczniejszy pod względem dostarczania typów danych.

Faktem jest, że przed wprowadzeniem generycznych, uogólniony kod w Javie mógłby zostać utworzony tylko przez referencje operacyjne, takie jak Object. Takie odniesienia można przypisać do dowolnego obiektu. W końcu wszystkie klasy w Javie są niejawnymi spadkobiercami klasy Object. Jednak to podejście jest potencjalnym źródłem wielu typów błędów związanych z bezpieczeństwem przy jawnym przekształcaniu obiektu Object w typ docelowy. Podczas korzystania z uogólnień wszystkie dostosowania są wykonywane niejawnie i automatycznie, co wyklucza nawet potencjalną możliwość wystąpienia błędów.


Generalizacja Java: opis i przykład

Spójrzmy na prosty przykład zastosowania uogólnień do zwykłej klasy na poniższym rysunku. Następnie przejdziemy do szczegółowego rozpatrzenia wszystkich niuansów i niuansów języka Java Generic.
Zwróć uwagę na sposób składania deklaracji pary. Bezpośrednio po nazwie klasy wyświetlane są nawiasy kwadratowe, w których wskazana jest litera T. Jest to rodzaj znaku zastępczego, który w procesie tworzenia instancji tej klasy zostanie zastąpiony określonym typem. Wygląda to tak: Pair obj = new Pair (). Należy zauważyć, że zamiast T można podać dowolną literę, ale z regułyużyj T, V lub E.


Uwaga: począwszy od ósmej wersji Javy, określając typ celu podczas deklarowania łącza, nawiasy kwadratowe w konstruktorze mogą pozostać puste. Tak więc powyższy przykład można zapisać w następujący sposób: Pair obj = new Pair & lt; & gt; (). Kiedy klasa jest zadeklarowana w ten sposób, możesz użyć tej litery w jej ciele zamiast określonych typów pól, łączy i metod zwracania obiektów. Ponieważ T, gdy obiekt klasy jest zastępowany przez określony typ, pierwsze i drugie pole w tym przypadku będzie miało typ całkowity. Zgodnie z logiką argumenty firstItem i secondItem, przekazywane do odpowiedniego konstruktora, powinny mieć również typ Integer lub jego podklasy. Jeśli spróbujesz wysłać typ danych, który różni się od tego, który został określony podczas tworzenia obiektu, kompilator nie przegapi tego błędu. Zatem konstruktor z argumentami podczas tworzenia obiektu będzie wyglądał następująco: Pair obj = new Pair & lt; & gt; (nowa liczba całkowita

, nowa liczba całkowita

). To samo dotyczy argumentów setFirst i setSecond methods. I jak już pewnie zgadłeś, getFirst i getSecond będą zwracać liczby całkowite.

Uogólniona klasa z kilkoma rodzajami parametrów

W uogólnionych klasach możliwe jest również zadeklarowanie kilku parametrów typu, które są podane w nawiasach narożnych za pomocą przecinka. W tym przypadku klasę Pair przedstawiono na poniższym rysunku.
Jak widać, podczas tworzenia instancji takiej klasy w nawiasach narożnych należy wskazać liczbę typów jako parametry. Jeśli znasz taką strukturę danych, jak na przykład Map, możesz to zauważyćstosuje się dokładnie tę samą zasadę. Tam pierwszy argument określa typ klucza, a drugi jest typem wartości. Należy zauważyć, że typy przekazywane podczas tworzenia obiektu argumentów mogą się pokrywać. Tak, poniższa deklaracja klasy Pair jest absolutnie poprawna: Pair obj.

Niektóre cechy uogólnień

Przed kontynuowaniem należy zauważyć, że kompilator Java nie tworzy żadnych różnych wersji klasy Pair. W rzeczywistości w procesie kompilacji usuwane są wszystkie informacje o typie uogólnionym. Zamiast tego odpowiednie typy są wykonywane przez utworzenie specjalnej wersji klasy Pair. Jednak w samym programie, tak jak poprzednio, istnieje jedna ogólna wersja tej klasy. Ten proces nazywa się typem Java Generic Cleanup. Zwróćmy uwagę na ważny punkt. Odsyłacze do różnych wersji tej samej klasy ogólnej java nie mogą wskazywać na ten sam obiekt. Oznacza to, że mamy dwie referencje: Pair obj1 i Pair obj2. Tak więc wystąpi błąd obj1 = obj2. Chociaż obie zmienne należą do typu Para, obiekty, do których się odnoszą, są różne. Jest to żywy przykład Java Generic Security.

Granice nakładane na uogólnione klasy

Ważne jest, aby wiedzieć, że uogólnienia mogą dotyczyć tylko typów referencyjnych, to znaczy, że są przekazywane do ogólnego argumentu java klasy, argument musi być koniecznie typu klasy. Takie proste typy, takie jak na przykład, lub długie podwójne, nie mogą być przesyłane. Innymi słowy, poniższa linia deklaracji klasy Pare jest nieprawidłowa: Pair obj. Jednak to ograniczenie nie stanowi poważnego problemu, jak w Javie dla wszystkichTyp pierwotny to odpowiednia powłoka klasy. Ściśle mówiąc, jeśli chcesz hermetyzować całą i logiczną wartość w klasie Pair, automatyczne pakowanie zrobi wszystko za Ciebie: Pair obj = new Pair & lt; & gt; (25 prawdy).
Jeszcze bardziej poważnym ograniczeniem jest niemożność stworzenia instancji parametru typu. Tak więc poniższy wiersz spowoduje błąd kompilacji: T first = new T (). Jest to oczywiste, ponieważ nie wiesz z góry, czy argument zostanie przekazany do pełnoprawnej klasy lub streszczenia, czy też całkowicie interfejsu. To samo dotyczy tworzenia tablic.

Ograniczone typy

Dość często zdarzają się sytuacje, w których należy ograniczyć listę typów, które można przekazać jako ogólny argument java. Załóżmy, że w naszej klasie Pair chcemy hermetyzować tylko wartości liczbowe dla dalszych operacji matematycznych nad nimi. Aby to zrobić, musimy określić górny limit parametru typu. Jest to realizowane za pomocą ogłoszenia superklasy, która jest dziedziczona przez wszystkie argumenty przekazywane w nawiasach trójkątnych. Będzie to wyglądać tak: Para par. W ten sposób kompilator dowiaduje się, że zamiast parametru T można podstawić klasę Number lub jedną z jej podklas. Jest to powszechne przyjęcie. Ograniczenia te są często używane w celu zapewnienia zgodności parametrów typu w tej samej klasie. Rozważmy przykład w parach Para par: klasa. Tutaj mówimy kompilatorowi, że typ T może być dowolny, a typ V musi koniecznie być typu T lub jedną z jego podklas. Ograniczenie "bottom" jest dokładnie takie samo, ale zamiast rozszerzeń słów, słowo jest napisanesuper Oznacza to, że deklaracja pary klas mówi, że zamiast T, ArrayList lub dowolna klasa lub użytkownik, który zatrudnia, może być podstawiony.

Ogólne metody i konstruktory Java

W języku Java, generalizacje można stosować nie tylko do klas, ale również do metod. Tak więc, uogólniona metoda może być zadeklarowana w zwykłej klasie.
Jak widać na powyższym rysunku, nie ma nic skomplikowanego w ogłoszeniu uogólnionej metody. Wystarczy przed obliczoną metodą wpisać nawiasy kątowe i określić w nich parametry typów. W przypadku konstruktora wszystko odbywa się w ten sam sposób:
Nawiasy kwadratowe w tym przypadku odnoszą się do nazwy konstruktora, ponieważ nie zwraca ona żadnego znaczenia. Wynikiem obu programów będzie: Ciąg całkowity

Powiązane publikacje