Generiske konstruktører i Java

1. Oversigt

Vi har tidligere diskuteret det grundlæggende i Java Generics. I denne vejledning ser vi på generiske konstruktører i Java.

En generisk konstruktør er en konstruktør, der har mindst en parameter af en generisk type.

Vi ser, at generiske konstruktører ikke behøver at være i en generisk klasse, og ikke alle konstruktører i en generisk klasse skal være generiske.

2. Ikke-generisk klasse

For det første har vi en simpel klasse Indgang, som ikke er en generisk klasse:

offentlig klasseindgang {private strengdata; privat int rang; }

I denne klasse tilføjer vi to konstruktører: en grundlæggende konstruktør med to parametre og en generisk konstruktør.

2.1. Grundlæggende konstruktør

Den første Indgang konstruktør er en simpel konstruktør med to parametre:

offentlig indtastning (String data, int rang) {this.data = data; this.rank = rang; }

Lad os nu bruge denne grundlæggende konstruktør til at oprette en Indgang objekt:

@Test offentlig ugyldighed givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK () {Entry entry = new Entry ("sample", 1); assertEquals ("prøve", entry.getData ()); assertEquals (1, entry.getRank ()); }

2.2. Generisk konstruktør

Dernæst er vores anden konstruktør en generisk konstruktør:

public Entry (E element) {this.data = element.toString (); this.rank = element.getRank (); }

Selvom Indgang klasse er ikke generisk, den har en generisk konstruktør, da den har en parameter element af typen E.

Den generiske type E er afgrænset og skal implementere begge dele Kan rangeres og Serialiserbar grænseflader.

Lad os nu se på Kan rangeres interface, som har en metode:

offentlig grænseflade Rankable {public int getRank (); }

Og antag, at vi har en klasse Produkt der implementerer Kan rangeres grænseflade:

offentlig klasse Produktværktøjer Rangable, Serializable {private String name; privat dobbelt pris; private int salg; offentligt produkt (strengnavn, dobbelt pris) {this.name = navn; denne pris = pris; } @ Override public int getRank () {retur salg; }}

Vi kan derefter bruge den generiske konstruktør til at oprette Indgang genstande ved hjælp af en Produkt:

@Test offentligt ugyldigt givetGenericConstructor_whenCreateNonGenericEntry_thenOK () {Produkt produkt = nyt produkt ("mælk", 2.5); product.setSales (30); Indgangsindgang = ny indgang (produkt); assertEquals (product.toString (), entry.getData ()); assertEquals (30, entry.getRank ()); }

3. Generisk klasse

Dernæst ser vi på en generisk klasse kaldet Generisk indgang:

offentlig klasse GenericEntry {private T-data; privat int rang; }

Vi tilføjer også de samme to typer konstruktører som det foregående afsnit i denne klasse.

3.1. Grundlæggende konstruktør

Lad os først skrive en simpel, ikke-generisk konstruktør til vores Generisk indgang klasse:

public GenericEntry (int rang) {this.rank = rang; }

Selv om Generisk indgang er en generisk klasse, dette er en simpel konstruktør, der ikke har en parameter af en generisk type.

Nu kan vi bruge denne konstruktør til at oprette en Generisk indgang:

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

3.2. Generisk konstruktør

Lad os derefter tilføje den anden konstruktør til vores klasse:

public GenericEntry (T data, int rank) {this.data = data; this.rank = rang; }

Dette er en generisk konstruktør, da den har en data parameter af den generiske type T. Bemærk, at vi ikke behøver at tilføje i konstruktørerklæringen, da den implicit er der.

Lad os nu teste vores generiske konstruktør:

@Test offentlig ugyldighed givenGenericConstructor_whenCreateGenericEntry_thenOK () {GenericEntry entry = new GenericEntry ("sample", 1); assertEquals ("prøve", entry.getData ()); assertEquals (1, entry.getRank ()); }

4. Generisk konstruktør med forskellig type

I vores generiske klasse kan vi også have en konstruktør med en generisk type, der adskiller sig fra klassens generiske type:

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

Det her Generisk indgang konstruktøren har en parameter element med type E, som er forskellig fra T type. Lad os se det i aktion:

@Test offentlig ugyldighed givenGenericConstructorWithDifferentType_whenCreateGenericEntry_thenOK () {Produkt produkt = nyt produkt ("mælk", 2.5); product.setSales (30); GenericEntry entry = new GenericEntry (product); assertEquals (produkt, entry.getData ()); assertEquals (30, entry.getRank ()); }

Noter det:

  • I vores eksempel brugte vi Produkt (E) for at oprette en Generisk indgang af typen Serialiserbar (T)
  • Vi kan kun bruge denne konstruktør, når parameteren af ​​typen E kan støbes til T

5. Flere generiske typer

Dernæst har vi den generiske klasse MapEntry med to generiske typer:

offentlig klasse MapEntry {privat K-nøgle; privat V-værdi; public MapEntry (K-tast, V-værdi) {this.key = key; this.value = værdi; }}

MapEntry har en generisk konstruktør med to parametre, hver af en anden type. Lad os bruge det i en simpel enhedstest:

@Test offentlig ugyldighed givenGenericConstructor_whenCreateGenericEntryWithTwoTypes_thenOK () {MapEntry entry = new MapEntry ("sample", 1); assertEquals ("prøve", entry.getKey ()); assertEquals (1, entry.getValue (). intValue ()); }

6. Jokertegn

Endelig kan vi bruge jokertegn i en generisk konstruktør:

public GenericEntry (Valgfri valgfri) {if (optional.isPresent ()) {this.data = (T) optional.get (); this.rank = optional.get (). getRank (); }}

Her brugte vi jokertegn i dette Generisk indgang konstruktør til at binde Valgfri type:

@Test offentlig ugyldighed givenGenericConstructorWithWildCard_whenCreateGenericEntry_thenOK () {Produkt produkt = nyt produkt ("mælk", 2,5); product.setSales (30); Valgfri valgfri = Valgfri. Af (produkt); GenericEntry post = ny GenericEntry (valgfri); assertEquals (produkt, entry.getData ()); assertEquals (30, entry.getRank ()); }

Bemærk, at vi skal være i stand til at caste den valgfri parametertype (i vores tilfælde Produkt) til Generisk indgang type (i vores tilfælde Serialiserbar).

7. Konklusion

I denne artikel lærte vi, hvordan man definerer og bruger generiske konstruktører i både generiske og ikke-generiske klasser.

Den fulde kildekode kan findes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found