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.