Varargovi u Javi

1. Uvod

Varargovi uvedeni su u Java 5 i pružaju kratki priručnik za metode koje podržavaju proizvoljan broj parametara jedne vrste.

U ovom ćemo članku vidjeti kako možemo koristiti ovu osnovnu Java značajku.

2. Prije Varargovi

Prije Jave 5, kad god smo željeli proslijediti proizvoljan broj argumenata, morali smo proslijediti sve argumente u nizu ili implementirati N metoda (po jedan za svaki dodatni parametar):

javni format niza () {...} javni format niza (vrijednost niza) {...} javni format niza (niz val1, niz val2) {...}

3. Korištenje Varargovi

Varargovi pomozite nam da izbjegnemo pisanje standardnog koda uvođenjem nove sintakse koja automatski može obraditi proizvoljan broj parametara - pomoću niza ispod haube.

Možemo ih definirati pomoću standardne deklaracije tipa, nakon koje slijedi elipsa:

public String formatWithVarArgs (String ... values) {// ...}

A sada našu metodu možemo nazvati proizvoljnim brojem argumenata, poput:

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

Kao što je ranije spomenuto, varargi su nizovi pa s njima moramo raditi baš kao što bismo radili s normalnim nizom.

4. Pravila

Varargovi su jednostavni za upotrebu. No, postoji nekoliko pravila koja moramo imati na umu:

  • Svaka metoda može imati samo jednu varargi parametar
  • The varargi argument mora biti zadnji parametar

5. Zagađenje gomile

Koristeći varargi može dovesti do takozvanog onečišćenja gomile. Da biste bolje razumjeli onečišćenje gomile, razmotrite ovo varargi metoda:

static String firstOfFirst (Popis ... nizovi) {Popis ints = Collections.singletonList (42); Objekt [] objekti = nizovi; objekti [0] = intova; // povratni nizovi zagađenja gomile [0] .get (0); // ClassCastException}

Ako u testu nazovemo ovu čudnu metodu:

Niz jedan = firstOfFirst (Arrays.asList ("one", "two"), Collections.emptyList ()); assertEquals ("jedan", jedan);

Dobili bismo ClassCastException iako ovdje nismo ni koristili nikakve eksplicitne uloge:

java.lang.ClassCastException: klasa java.lang.Integer ne može se prebaciti na klasu java.lang.String

5.1. Sigurna upotreba

Svaki put kad koristimo varargi, Java kompajler stvara niz za zadržavanje zadanih parametara. U ovom slučaju, kompajler stvara niz s komponentama generičkog tipa za držanje argumenata.

Kad koristimo varargi s generičkim tipovima, budući da postoji potencijalni rizik od fatalne iznimke tijekom izvođenja, Java prevodilac nas upozorava na moguću nesigurnost varargi upotreba:

upozorenje: [varargs] Moguće onečišćenje gomile od parametriziranog vararga tipa T

The varargi uporaba je sigurna samo i samo ako:

  • Ne pohranjujemo ništa u implicitno stvorenom polju. U ovom smo primjeru spremili Popis u tom nizu
  • Ne dopuštamo da referenca na generirani niz pobjegne metodi (više o tome kasnije)

Ako smo sigurni da metoda sama sigurno koristi vararge, možemo ih koristiti @SafeVarargs da potisne upozorenje.

Jednostavno rečeno, varargi upotreba je sigurna ako ih koristimo za prijenos promjenjivog broja argumenata s pozivatelja na metodu i ništa više!

5.2. Bježeći Varargovi Referenca

Razmotrimo još jednu nesigurnu uporabu varargi:

statički T [] toArray (T ... argumenti) {argumenti za povratak; }

U početku bi se moglo činiti da toArray metoda je potpuno bezopasna. Međutim, jer dopušta da niz varargova pobjegne pozivatelju, krši drugo pravilo sigurnosti varargi.

Da bismo vidjeli kako ova metoda može biti opasna, upotrijebimo je u drugoj metodi:

statički T [] returnAsIs (T a, T b) {povratak uArray (a, b); }

Tada ako pozovemo ovu metodu:

String [] args = returnAsIs ("Jedan", "Dva");

Opet bismo dobili a ClassCastException. Evo što se događa kada nazovemo returnAsIs metoda:

  • Proći a i b prema toArray metodom, Java treba stvoriti niz
  • Budući da je Objekt[] može sadržavati predmete bilo koje vrste, kompajler ih stvara
  • The toArray metoda vraća zadani Objekt[] pozivatelju
  • Budući da mjesto poziva očekuje a Niz[], kompajler pokušava baciti Objekt[] do očekivanog Niz[], dakle ClassCastException

Za detaljniju raspravu o onečišćenju gomile, toplo se preporučuje pročitati točku 32 Efektivne Jave Joshua Bloch

6. Zaključak

Varargovi može učiniti da mnogi jezici nestanu na Javi.

I, zahvaljujući njihovom implicitnom autoboks do i iz Polje, oni igraju ulogu u provjeri našeg koda u budućnosti.

Kao i uvijek, svi primjeri koda iz ovog članka mogu biti dostupni u našem GitHub spremištu.