Generički konstruktori u Javi

1. Pregled

Prethodno smo razgovarali o osnovama Java Generics-a. U ovom uputstvu ćemo pogledati Generičke konstruktore u Javi.

Generički konstruktor je konstruktor koji ima barem jedan parametar generičkog tipa.

Vidjet ćemo da generički konstruktori ne moraju biti u generičkoj klasi, a ne moraju svi konstruktori u generičkoj klasi biti generički.

2. Neuobičajena klasa

Prvo, imamo jednostavnu nastavu Ulazak, koji nije generička klasa:

ulazak u javnu klasu {podaci privatnog niza; privatni int čin; }

U ovu ćemo klasu dodati dva konstruktora: osnovni konstruktor s dva parametra i generički konstruktor.

2.1. Osnovni konstruktor

Prvi Ulazak konstruktor je jednostavan konstruktor s dva parametra:

javni unos (podaci niza, int rank) {this.data = podaci; this.rank = rank; }

Sada, upotrijebimo ovaj osnovni konstruktor za stvaranje Ulazak objekt:

@Test javna praznina givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK () {Entry entry = new Entry ("sample", 1); assertEquals ("uzorak", entry.getData ()); assertEquals (1, entry.getRank ()); }

2.2. Generički konstruktor

Dalje, naš drugi konstruktor je generički konstruktor:

javni unos (E element) {this.data = element.toString (); this.rank = element.getRank (); }

iako Ulazak klasa nije generička, ona ima generički konstruktor, jer ima parametar element tipa E.

Generički tip E je ograničen i trebao bi provoditi oboje Rankable i Serijalizirati sučelja.

Pogledajmo sada Rankable sučelje, koje ima jednu metodu:

javno sučelje Rankable {public int getRank (); }

I, pretpostavimo da imamo nastavu Proizvod koja provodi Rankable sučelje:

proizvod javne klase implementira Rankable, Serializable {ime privatnog niza; privatna dvostruka cijena; privatna int prodaja; javni proizvod (naziv niza, dvostruka cijena) {this.name = name; this.price = cijena; } @Override public int getRank () {povrat prodaje; }}

Tada možemo koristiti generički konstruktor za stvaranje Ulazak predmeti koji koriste a Proizvod:

@Test javna praznina givenGenericConstructor_whenCreateNonGenericEntry_thenOK () {Proizvod proizvoda = novi proizvod ("mlijeko", 2.5); product.setSales (30); Unos unosa = novi unos (proizvod); assertEquals (product.toString (), entry.getData ()); assertEquals (30, entry.getRank ()); }

3. Generička klasa

Dalje ćemo pogledati generičku klasu pod nazivom GenericEntry:

javna klasa GenericEntry {privatni T podaci; privatni int čin; }

Također ćemo dodati iste dvije vrste konstruktora kao i prethodni odjeljak u ovu klasu.

3.1. Osnovni konstruktor

Prvo, napišimo jednostavan, generički konstruktor za naš GenericEntry razred:

javni GenericEntry (int rank) {this.rank = rank; }

Čak iako GenericEntry je generička klasa, ovo je jednostavan konstruktor koji nema parametar generičkog tipa.

Sada ovaj konstruktor možemo koristiti za stvaranje a GenericEntry:

@Test javna praznina givenNonGenericConstructor_whenCreateGenericEntry_thenOK () {GenericEntry entry = new GenericEntry (1); assertNull (entry.getData ()); assertEquals (1, entry.getRank ()); }

3.2. Generički konstruktor

Dalje, dodajmo drugi konstruktor u našu klasu:

javni GenericEntry (T podaci, int rank) {this.data = podaci; this.rank = rank; }

Ovo je generički konstruktor, jer ima podaci parametar generičkog tipa T. Imajte na umu da ne trebamo dodavati u deklaraciji konstruktora, jer je implicitno tamo.

Sada, testirajmo naš generički konstruktor:

@Test javna praznina givenGenericConstructor_whenCreateGenericEntry_thenOK () {GenericEntry entry = new GenericEntry ("sample", 1); assertEquals ("uzorak", entry.getData ()); assertEquals (1, entry.getRank ()); }

4. Generički konstruktor različite vrste

U našoj generičkoj klasi također možemo imati konstruktor s generičkim tipom koji se razlikuje od generičkog tipa klase:

javni GenericEntry (E element) {this.data = (T) element; this.rank = element.getRank (); }

Ovaj GenericEntry konstruktor ima parametar element s tipom E, koji se razlikuje od T tip. Pogledajmo na djelu:

@Test javna praznina givenGenericConstructorWithDifferentType_whenCreateGenericEntry_thenOK () {Proizvod proizvoda = novi proizvod ("mlijeko", 2.5); product.setSales (30); Unos GenericEntry = novi GenericEntry (proizvod); assertEquals (product, entry.getData ()); assertEquals (30, entry.getRank ()); }

Imajte na umu da:

  • U našem smo primjeru koristili Proizvod (E) za stvaranje a GenericEntry tipa Serijalizirati (T)
  • Ovaj konstruktor možemo koristiti samo kada je parametar type E može se baciti na T

5. Više generičkih vrsta

Dalje, imamo generički razred MapEntry s dvije generičke vrste:

javna klasa MapEntry {privatni K ključ; privatna V vrijednost; javni MapEntry (ključ K, vrijednost V) {this.key = key; this.value = vrijednost; }}

MapEntry ima jedan generički konstruktor s dva parametra, svaki različitog tipa. Upotrijebimo ga u jednostavnom jediničnom testu:

@Test javna praznina givenGenericConstructor_whenCreateGenericEntryWithTwoTypes_thenOK () {MapEntry entry = new MapEntry ("uzorak", 1); assertEquals ("uzorak", entry.getKey ()); assertEquals (1, entry.getValue (). intValue ()); }

6. Zamjenski znakovi

Napokon, možemo koristiti zamjenske znakove u generičkom konstruktoru:

javni GenericEntry (nije obavezno) {if (nije obavezno.isPresent ()) {this.data = (T) nije obavezno.get (); this.rank = neobvezno.get (). getRank (); }}

Evo, u tome smo koristili zamjenske znakove GenericEntry konstruktor za vezanje Neobvezno tip:

@Test javna praznina givenGenericConstructorWithWildCard_whenCreateGenericEntry_thenOK () {Proizvod proizvoda = novi proizvod ("mlijeko", 2.5); product.setSales (30); Neobvezno neobavezno = Neobvezno.of (proizvod); Unos GenericEntry = novi GenericEntry (nije obavezno); assertEquals (product, entry.getData ()); assertEquals (30, entry.getRank ()); }

Imajte na umu da bismo trebali moći emitirati opcijski tip parametra (u našem slučaju, Proizvod) prema GenericEntry vrsta (u našem slučaju, Serijalizirati).

7. Zaključak

U ovom smo članku naučili kako definirati i koristiti generičke konstruktore i u generičkim i u generičkim klasama.

Cjeloviti izvorni kod možete pronaći na GitHubu.