Varargs Java-ban
1. Bemutatkozás
Varargs ben vezették be Java 5 és rövid leírást ad azokról a módszerekről, amelyek tetszőleges számú paramétert támogatnak.
Ebben a cikkben megtudjuk, hogyan használhatjuk ezt a Java alapfunkciót.
2. Előtte Varargs
A Java 5 előtt, amikor tetszőleges számú argumentumot akartunk átadni, át kellett adnunk az összes argumentumot egy tömbben, vagy N metódust kellett végrehajtanunk (egyet minden további paraméterhez):
public String format () {...} public String format (String value) {...} public String format (String val1, String val2) {...}
3. Használata Varargs
Varargs segítsen elkerülni a kazán kód írását az új szintaxis bevezetésével, amely tetszőleges számú paramétert képes automatikusan kezelni - a motorháztető alatt található tömb segítségével.
Meghatározhatjuk őket egy szabványos típusú deklarációval, amelyet egy ellipszis követ:
public String formatWithVarArgs (String ... értékek) {// ...}
És most tetszőleges számú argumentummal hívhatjuk meg módszerünket, például:
formatWithVarArgs (); formatWithVarArgs ("a", "b", "c", "d");
Mint korábban említettük, varargs tömbök, ezért velük kell dolgozni, ugyanúgy, mint egy normál tömböt.
4. Szabályok
Varargs használata egyszerű. De van néhány szabály, amelyet szem előtt kell tartanunk:
- Minden módszernek csak egy lehet varargs paraméter
- A varargs argumentumnak kell lennie az utolsó paraméternek
5. Halomszennyezés
Használata varargs úgynevezett kupacszennyezéshez vezethet. A halomszennyezés jobb megértése érdekében fontolja meg ezt varargs módszer:
statikus String firstOfFirst (List ... stringek) {List ints = Gyűjtemények.singletonList (42); Object [] objektumok = karakterláncok; tárgyak [0] = ints; // Halomszennyezés visszatérő karakterláncai [0] .get (0); // ClassCastException}
Ha ezt a furcsa módszert nevezzük egy teszt során:
Első karakterlánc = firstOfFirst (Tömbök.asList ("egy", "kettő"), Gyűjtemények.emptyList ()); assertEquals ("egy", egy);
Kapnánk egy ClassCastException annak ellenére, hogy itt nem is használtunk explicit típusú szereplőket:
java.lang.ClassCastException: java.lang.Integer osztály nem adható át a java.lang.String osztályba
5.1. Biztonságos használat
Minden alkalommal, amikor használunk varargs, a Java fordító tömböt hoz létre a megadott paraméterek megtartására. Ebben az esetben a fordító létrehoz egy tömböt általános típusú összetevőkkel az argumentumok megtartására.
Amikor használjuk varargs általános típusokkal, mivel fennáll a végzetes futásidejű kivétel kockázata, a Java fordító figyelmeztet minket egy esetleges nem biztonságos varargs használat:
figyelmeztetés: [varargs] Lehetséges kupacszennyezés a paraméterezett vararg típusú T-től
A varargs a használat akkor és csak akkor biztonságos, ha:
- Az implicit módon létrehozott tömbben nem tárolunk semmit. Ebben a példában valóban tároltunk egy Lista abban a tömbben
- Nem hagyjuk, hogy a létrehozott tömbre való hivatkozás elkerülje a módszert (erről bővebben később)
Ha biztosak vagyunk benne, hogy maga a módszer biztonságosan használja a varargokat, akkor használhatjuk @SafeVarargs hogy elnyomja a figyelmeztetést.
Leegyszerűsítve: varargs a használat akkor biztonságos, ha változó számú argumentum átadására használjuk őket a hívótól a módszerig, és semmi mást!
5.2. Menekülés Varargs Referencia
Vegyük fontolóra a másik nem biztonságos használatát varargs:
statikus T [] toArray (T ... érvek) {return argumentumok; }
Eleinte úgy tűnhet, hogy a array módszer teljesen ártalmatlan. Mivel azonban a varargs tömb elhagyta a hívót, megsérti a széf második szabályát varargs.
Ha meg szeretné tudni, hogy ez a módszer hogyan lehet veszélyes, használjuk egy másik módszerben:
statikus T [] returnAsIs (T a, T b) {visszatérés Array (a, b); }
Akkor, ha ezt a módszert hívjuk:
Karakterlánc [] args = returnAsIs ("egy", "kettő");
Megint kapnánk egy ClassCastException. Itt történik, mi történik, amikor felhívjuk a returnAsIs módszer:
- Átmenni a és b hoz array módszerrel a Java-nak létre kell hoznia egy tömböt
- Mivel a Tárgy[] bármilyen típusú elemet képes tárolni, a fordító létrehoz egyet
- A array metódus adja vissza az adott Tárgy[] a hívónak
- Mivel a hívóhely arra számít, hogy a Húr[], a fordító megpróbálja leadni a Tárgy[] a vártnak Húr[], ezért a ClassCastException
A halomszennyezésről szóló részletesebb vita érdekében erősen ajánlott elolvasni Joshua Bloch Effective Java 32. cikkét.
6. Következtetés
Varargs sok kazán lemerülhet a Java-ban.
És, köszönhetően implicit autoboxing ki és vissza Sor, szerepet játszanak a kódunk jövőbiztosításában.
Mint mindig, a cikk összes kódpéldája elérhető a GitHub-adattárunkban.