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.