Generické konštruktory v Jave
1. Prehľad
Predtým sme diskutovali o základoch Java Generics. V tomto výučbe sa pozrieme na Generické konštruktory v Jave.
Generický konštruktor je konštruktor, ktorý má aspoň jeden parameter generického typu.
Uvidíme, že generické konštruktory nemusia byť v generickej triede a nie všetky konštruktory v generickej triede musia byť generické.
2. Negenerická trieda
Najskôr máme jednoduchú triedu Vstup, ktorá nie je generickou triedou:
public class Entry {private String data; hodnosť súkromného int; }
V tejto triede pridáme dva konštruktory: základný konštruktor s dvoma parametrami a všeobecný konštruktor.
2.1. Základný konštruktor
Prvý Vstup konštruktor je jednoduchý konštruktor s dvoma parametrami:
public Entry (String data, int rank) {this.data = data; this.rank = poradie; }
Teraz použijeme tento základný konštruktor na vytvorenie súboru Vstup objekt:
@Test public void givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK () {Entry entry = new Entry ("sample", 1); assertEquals ("sample", entry.getData ()); assertEquals (1, entry.getRank ()); }
2.2. Generický konštruktor
Ďalej je náš druhý konštruktor generický konštruktor:
public Entry (E element) {this.data = element.toString (); this.rank = element.getRank (); }
Napriek tomu Vstup trieda nie je všeobecná, má všeobecný konštruktor, pretože má parameter element typu E.
Všeobecný typ E je obmedzený a mal by implementovať oboje Rankable a Serializovateľné rozhrania.
Teraz sa pozrime na Rankable rozhranie, ktoré má jednu metódu:
verejné rozhranie Rankable {public int getRank (); }
A predpokladajme, že máme triedu Výrobok ktorý vykonáva Rankable rozhranie:
public class Produkt implementuje Rankable, Serializable {private String name; dvojitá súkromná cena; súkromný int predaj; public Product (názov reťazca, dvojnásobná cena) {this.name = name; this.price = price; } @Override public int getRank () {spätný predaj; }}
Potom môžeme na vytvorenie použiť generický konštruktor Vstup predmety pomocou a Výrobok:
@Test public void givenGenericConstructor_whenCreateNonGenericEntry_thenOK () {Product product = new Product ("milk", 2.5); product.setSales (30); Vstupný záznam = nový Záznam (produkt); assertEquals (product.toString (), entry.getData ()); assertEquals (30, entry.getRank ()); }
3. Generická trieda
Ďalej sa pozrieme na generickú triedu s názvom GenericEntry:
verejná trieda GenericEntry {súkromné T dáta; hodnosť súkromného int; }
Rovnako pridáme do tejto triedy rovnaké dva typy konštruktorov ako v predchádzajúcej časti.
3.1. Základný konštruktor
Najskôr si napíšeme jednoduchý, generický konštruktor pre naše GenericEntry trieda:
public GenericEntry (int rank) {this.rank = rank; }
Aj napriek tomu GenericEntry je generická trieda, jedná sa o jednoduchý konštruktor, ktorý nemá parameter generického typu.
Teraz môžeme pomocou tohto konštruktora vytvoriť a GenericEntry:
@Test public void givenNonGenericConstructor_whenCreateGenericEntry_thenOK () {položka GenericEntry = nový GenericEntry (1); assertNull (entry.getData ()); assertEquals (1, entry.getRank ()); }
3.2. Generický konštruktor
Ďalej pridajme do našej triedy druhý konštruktor:
public GenericEntry (T data, int rank) {this.data = data; this.rank = poradie; }
Toto je všeobecný konštruktor, pretože má údaje parameter generického typu T. Upozorňujeme, že nemusíme pridávať v deklarácii konštruktora, pretože je to implicitne tam.
Teraz otestujme náš generický konštruktor:
@Test public void givenGenericConstructor_whenCreateGenericEntry_thenOK () {položka GenericEntry = nový GenericEntry ("vzorka", 1); assertEquals ("sample", entry.getData ()); assertEquals (1, entry.getRank ()); }
4. Generický konštruktor s rôznym typom
V našej generickej triede môžeme mať aj konštruktor s generickým typom, ktorý sa líši od generického typu triedy:
public GenericEntry (E element) {this.data = (T) element; this.rank = element.getRank (); }
Toto GenericEntry konštruktor má parameter element s typom E, ktorá sa líši od T typu. Pozrime sa na to v akcii:
@Test public void givenGenericConstructorWithDifferentType_whenCreateGenericEntry_thenOK () {Product product = new Product ("milk", 2.5); product.setSales (30); Vstup GenericEntry = nový GenericEntry (produkt); assertEquals (product, entry.getData ()); assertEquals (30, entry.getRank ()); }
Poznač si to:
- V našom príklade sme použili Výrobok (E) na vytvorenie a GenericEntry typu Serializovateľné (T)
- Tento konštruktor môžeme použiť, iba ak je parametrom typu E je možné obsadiť do T
5. Viacero všeobecných typov
Ďalej tu máme generickú triedu MapEntry s dvoma generickými typmi:
verejná trieda MapEntry {súkromný K kľúč; súkromná hodnota V; public MapEntry (kľúč K, hodnota V) {this.key = kľúč; this.value = value; }}
MapEntry má jeden generický konštruktor s dvoma parametrami, každý iného typu. Použime to v jednoduchom teste jednotky:
@Test public void givenGenericConstructor_whenCreateGenericEntryWithTwoTypes_thenOK () {MapEntry entry = new MapEntry ("sample", 1); assertEquals ("sample", entry.getKey ()); assertEquals (1, entry.getValue (). intValue ()); }
6. Zástupné znaky
Nakoniec môžeme zástupné znaky použiť v generickom konštruktore:
public GenericEntry (voliteľné voliteľné) {if (optional.isPresent ()) {this.data = (T) optional.get (); this.rank = optional.get (). getRank (); }}
Tu sme v tomto použili zástupné znaky GenericEntry konštruktér na zviazanie Voliteľné typ:
@Test public void givenGenericConstructorWithWildCard_whenCreateGenericEntry_thenOK () {Product product = new Product ("milk", 2.5); product.setSales (30); Voliteľné voliteľné = Voliteľné.of (produktu); Vstup GenericEntry = nový GenericEntry (voliteľné); assertEquals (product, entry.getData ()); assertEquals (30, entry.getRank ()); }
Upozorňujeme, že by sme mali byť schopní odovzdať voliteľný typ parametra (v našom prípade Výrobok) do GenericEntry typ (v našom prípade Serializovateľné).
7. Záver
V tomto článku sme sa naučili, ako definovať a používať generické konštruktory v generických aj negenerických triedach.
Celý zdrojový kód nájdete na GitHub.