Varargs i Java

1. Introduksjon

Varargs ble introdusert i Java 5 og gi en kort hånd for metoder som støtter et vilkårlig antall parametere av en type.

I denne artikkelen vil vi se hvordan vi kan bruke denne kjerne-Java-funksjonen.

2. Før Varargs

Før Java 5, hver gang vi ønsket å sende et vilkårlig antall argumenter, måtte vi sende alle argumentene i en matrise eller implementere N-metoder (en for hver ekstra parameter):

offentlig strengformat () {...} offentlig strengformat (strengverdi) {...} offentlig strengformat (streng val1, streng val2) {...}

3. Bruk av Varargs

Varargs hjelpe oss med å unngå å skrive kjelekode ved å introdusere den nye syntaksen som kan håndtere et vilkårlig antall parametere automatisk - ved hjelp av en matrise under panseret.

Vi kan definere dem ved hjelp av en standard typedeklarasjon, etterfulgt av en ellips:

offentlig strengformatWithVarArgs (streng ... verdier) {// ...}

Og nå kan vi kalle metoden vår med et vilkårlig antall argumenter, som:

formatWithVarArgs (); formatWithVarArgs ("a", "b", "c", "d");

Som nevnt tidligere, varargs er matriser, så vi må jobbe med dem akkurat som vi ville jobbe med et vanlig utvalg.

4. Regler

Varargs er enkle å bruke. Men det er noen få regler vi må huske på:

  • Hver metode kan bare ha en varargs parameter
  • De varargs argumentet må være den siste parameteren

5. Haugforurensning

Ved hjelp av varargs kan føre til såkalt Heap Pollution. For å bedre forstå haugforurensningen, bør du vurdere dette varargs metode:

statisk streng førstOfFirst (Liste ... strenger) {Liste ints = Collections.singletonList (42); Objekt [] objekter = strenger; objekter [0] = ints; // Hengeforurensningstrenger [0] .get (0); // ClassCastException}

Hvis vi kaller denne rare metoden i en test:

Streng en = firstOfFirst (Arrays.asList ("en", "to"), Collections.emptyList ()); assertEquals ("en", en);

Vi ville fått en ClassCastException selv om vi ikke en gang brukte noen eksplisitte type casts her:

java.lang.ClassCastException: klasse java.lang.Integer kan ikke kastes til klasse java.lang.String

5.1. Sikker bruk

Hver gang vi bruker varargs, oppretter Java-kompilatoren en matrise som inneholder de gitte parametrene. I dette tilfellet oppretter kompilatoren en matrise med komponenter av generisk type for å beholde argumentene.

Når vi bruker varargs med generiske typer, da det er en potensiell risiko for et dødelig unntak for kjøretid, advarer Java-kompilatoren oss om en mulig usikker varargs bruk:

advarsel: [varargs] Mulig haugforurensning fra parametriserte vararg type T

De varargs bruk er trygt hvis og bare hvis:

  • Vi lagrer ikke noe i den implisitt opprettede matrisen. I dette eksemplet lagret vi en Liste i den matrisen
  • Vi lar ikke en referanse til den genererte matrisen unnslippe metoden (mer om dette senere)

Hvis vi er sikre på at selve metoden trygt bruker vargs, kan vi bruke @SafeVarargs for å undertrykke advarselen.

Enkelt sagt, den varargs bruk er trygt hvis vi bruker dem til å overføre et variabelt antall argumenter fra innringeren til metoden og ingenting mer!

5.2. Rømmer Varargs Henvisning

La oss vurdere en annen usikker bruk av varargs:

statisk T [] til Array (T ... argumenter) {returner argumenter; }

Først kan det se ut til at toArray metoden er helt ufarlig. Imidlertid, fordi det lar varargs-arrayet flykte til den som ringer, bryter det den andre regelen om safe varargs.

For å se hvordan denne metoden kan være farlig, la oss bruke den i en annen metode:

statisk T [] returnAsIs (T a, T b) {tilbake til Array (a, b); }

Så hvis vi kaller denne metoden:

Streng [] args = returnAsIs ("One", "Two");

Vi vil igjen få en ClassCastException. Her er hva som skjer når vi kaller returnAsIs metode:

  • Å sende en og b til toArray metode, må Java opprette en matrise
  • Siden Gjenstand[] kan inneholde gjenstander av hvilken som helst type, lager kompilatoren en
  • De toArray metoden returnerer den gitte Gjenstand[] til innringeren
  • Siden anropssiden forventer a Streng [], kompilatoren prøver å kaste Gjenstand[] til det forventede Streng [], derav ClassCastException

For en mer detaljert diskusjon om haugeforurensning, anbefales det sterkt å lese punkt 32 i Effektiv Java av Joshua Bloch.

6. Konklusjon

Varargs kan få mye kokeplate til å forsvinne i Java.

Og takket være deres implisitte autoboksing til og fra Array, de spiller en rolle i fremtidssikring av koden vår.

Som alltid kan alle kodeeksempler fra denne artikkelen være tilgjengelige i GitHub-depotet vårt.


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