A metódus aláírása tartalmazza a Return típust a Java-ban?
1. Áttekintés
A method aláírás csak a Java egész metódusdefiníciójának részhalmaza. Így az aláírás pontos anatómiája zavart okozhat.
Ebben az oktatóanyagban megismerjük a módszer aláírásának elemeit és annak következményeit a Java programozásban.
2. Módszer Aláírás
A Java-ban használt módszerek támogatják a túlterhelést, ami azt jelenti, hogy ugyanazon osztályban vagy az osztályok hierarchiájában több, azonos névvel rendelkező módszer is meghatározható. Ezért a fordítónak képesnek kell lennie statikusan lekötni azt a módszert, amelyre az ügyfél kódja hivatkozik. Emiatt a módszer az aláírás egyedileg azonosítja az egyes módszereket.
Az Oracle szerint a módszer az aláírás a névből és a paramétertípusokból áll. Ezért a metódus deklarációjának összes többi eleme, például a módosítók, a visszatérés típusa, a paraméterek neve, a kivétellista és a törzs nem része az aláírásnak.
Vizsgáljuk meg közelebbről a módszer túlterhelését és annak kapcsolatát a módszer aláírásaival.
3. Túlterhelési hibák
Vegyük fontolóra a következő kódot:
public void print () {System.out.println ("Az aláírás: print ()"); } public void print (int paraméter) {System.out.println ("Az aláírás: print (int)"); }
Mint láthatjuk, a kód fordít, mivel a módszereknek különböző paramétertípus-listái vannak. Valójában a fordító bármely hívást determinisztikusan köthet az egyikhez vagy a másikhoz.
Most teszteljük, hogy legális-e a túlterhelés a következő módszer hozzáadásával:
public int print () {System.out.println ("Az aláírás: print ()"); visszatér 0; }
Fordításkor kapunk egy „már osztályban definiált metódust” hibát. Ez bizonyítja a módszert A return típus nem része a metódus aláírásának.
Próbáljuk meg ugyanezt a módosítókkal:
private final void print () {System.out.println ("Az aláírás: print ()"); }
Még mindig ugyanazt a "metódust már definiáltuk az osztályban" hibát látjuk. Ezért a módszer az aláírás nem függ a módosítóktól.
A túlterhelés a dobott kivételek megváltoztatásával az alábbiak hozzáadásával tesztelhető:
public void print () dobja az IllegalStateException {System.out.println ("Az aláírás: print ()"); dobja az új IllegalStateException () -t; }
Ismét látjuk a „módszer már osztályban definiálva” hibát, jelezve a dobási nyilatkozat nem lehet az aláírás része.
Utoljára azt tesztelhetjük, hogy a paraméterek nevének megváltoztatása lehetővé teszi-e a túlterhelést. Adjuk hozzá a következő módszert:
public void print (int anotherParameter) {System.out.println ("Az aláírás: print (int)"); }
A várakozásoknak megfelelően ugyanazt az összeállítási hibát kapjuk. Ez azt jelenti A paraméternevek nem befolyásolják a metódus aláírását.
3. Általános és típusú törlés
Általános paraméterekkel, a típusú törlés megváltoztatja a tényleges aláírást. Valójában ütközést okozhat egy másik módszerrel, amely az általános típus felső határát használja az általános jogkivonat helyett.
Vegyük fontolóra a következő kódot:
public class OverloadingErrors {public void printElement (T t) {System.out.println ("Az aláírás: printElement (T)"); } public void printElement (Serializable o) {System.out.println ("Az aláírás: printElement (Serializable)"); }}
Annak ellenére, hogy az aláírások eltérőnek tűnnek, a fordító a statikus törlés után nem tudja statikusan lekötni a helyes módszert.
Láthatjuk, hogy a fordító kicseréli T a felső határral, Serializálható, típusú törlés miatt. Így ütközik a kifejezetten használt módszerrel Sorosítható.
Ugyanezt az eredményt látnánk az alaptípusnál is Tárgy amikor az általános típusnak nincs kötése.
4. Paraméterlisták és polimorfizmus
A módszer aláírása figyelembe veszi a pontos típusokat. Ez azt jelenti, hogy túlterhelhetünk egy olyan módszert, amelynek paramétertípusa alosztály vagy szuperosztály.
Különös figyelmet kell fordítanunk azonban a a statikus kötés megkísérli a polimorfizmus, az auto-box és a típus promóció használatát.
Vessünk egy pillantást a következő kódra:
public Számösszeg (Egész szám1, Egész szám2) {System.out.println ("Egész számok hozzáadása"); visszatérési kifejezés1 + tag2; } public Számösszeg (Számtermet1, Számtermet2) {System.out.println ("Számok hozzáadása"); return term1.doubleValue () + term2.doubleValue (); } public Számösszeg (Object term1, Object term2) {System.out.println ("Objektumok hozzáadása"); return term1.hashCode () + term2.hashCode (); }
A fenti kód teljesen legális és összeáll. Zavar lehet a metódusok meghívásakor, mivel nemcsak a pontos metódus-aláírást kell ismernünk, hanem azt is, hogy a Java statikusan kötődik-e a tényleges értékek alapján.
Fedezzünk fel néhány módszerhívást, amelyek végül kötődnek összeg (egész, egész):
StaticBinding obj = new StaticBinding (); obj.sum (Integer.valueOf (2), Integer.valueOf (3)); obj.sum (2, 3); obj.sum (2, 0x1);
Az első hívásnál megvan a pontos paramétertípus Egész, Egész. A második híváskor a Java automatikusan bekapcsol int nak nek Egész szám nekünk. Végül a Java átalakítja a bájt értéket 0x1 nak nek int típusú promóció útján, majd automatikusan bejelöli Egész szám.
Hasonlóképpen, a következő hívások vannak, amelyek kötődnek összeg (szám, szám):
obj.sum (2,0d, 3,0d); obj.sum (Float.valueOf (2), Float.valueOf (3));
Az első híváskor megvan kettős értékek, amelyek automatikusan bekerülnek Kettős. Aztán a polimorfizmus révén Kettős mérkőzések Szám. Ugyanúgy, Úszó mérkőzések Szám a második hívásra.
Figyeljük meg, hogy mindkettő Úszó és Kettős örökölni Szám és Tárgy. Az alapértelmezett kötés azonban a Szám. Ez annak a ténynek köszönhető, hogy a Java automatikusan illeszkedik a legközelebbi szupertípusokhoz, amelyek megfelelnek a metódus aláírásának.
Most vegyük fontolóra a következő metódushívást:
obj.sum (2, "János");
Ebben a példában van egy int nak nek Egész szám auto-box az első paraméterhez. Nincs azonban összeg (egész, húr) ennek a metódusnévnek a túlterhelése. Ennek következtében a Java végigfuttatja az összes paraméter szuper-típust, hogy a legközelebbi szülőtől átküldje Tárgy amíg talál egyezést. Ebben az esetben ahhoz kötődik összeg (Object, Object).
Az alapértelmezett kötés megváltoztatásához használhatunk explicit paraméter-öntést alábbiak szerint:
obj.sum ((Objektum) 2, (Objektum) 3); obj.sum ((Szám) 2, (Szám) 3);
5. Vararg paraméterek
Most fordítsuk figyelmünket arra, hogyan varargs befolyásolják a módszer hatékony aláírását és statikus kötés.
Itt van egy túlterhelt módszerünk varargs:
public Számösszeg (Object term1, Object term2) {System.out.println ("Objektumok hozzáadása"); return term1.hashCode () + term2.hashCode (); } public Számösszeg (Object term1, Object ... term2) {System.out.println ("Változó argumentumok hozzáadása:" + term2.length); int eredmény = term1.hashCode (); for (Object o: term2) {eredmény + = o.hashCode (); } visszatérési eredmény; }
Mi tehát a módszerek hatékony aláírása? Ezt már láttuk összeg (objektum, objektum) az első aláírása. A változó argumentumok lényegében tömbök, tehát a fordítás utáni második tényleges aláírása az összeg (Object, Object []).
Trükkös kérdés, hogyan választhatjuk ki a kötés módját, amikor csak két paraméterünk van?
Vegyük fontolóra a következő felhívásokat:
obj.sum (új objektum (), új objektum ()); obj.sum (new Object (), new Object (), new Object ()); obj.sum (new Object (), new Object [] {new Object ()});
Nyilvánvaló, hogy az első hívás kapcsolódni fog összeg (objektum, objektum) a második pedig összeg (Object, Object []). Ahhoz, hogy a Java két objektummal hívja meg a második metódust, egy tömbbe kell csomagolnunk, mint a harmadik hívásban.
Az utolsó dolog, amit itt meg kell jegyezni, hogy a következő módszer deklarálása ütközik a vararg verzióval:
public Számösszeg (Object term1, Object [] term2) {// ...}
6. Következtetés
Ebben az oktatóanyagban megtudtuk, hogy a metódus aláírások a névből és a paramétertípusok listájából állnak. A módosítók, a visszatérés típusa, a paraméterek nevei és a kivétellista nem tehet különbséget a túlterhelt módszerek között, és így nem képezik részét az aláírásnak.
Megvizsgáltuk azt is, hogy a típusú törlés és a varargs hogyan rejti el a hatékony módszeraláírást, és hogyan tudjuk felülírni a Java statikus metóduskötését.
Szokás szerint a cikkben bemutatott összes kódminta elérhető a GitHubon.