Programovanie

Metóda preťaženia v JVM

Vitajte v novom Vyzyvatelia Java blog! Tento blog je venovaný náročným konceptom v programovaní v Jave. Osvojte si ich a budete na dobrej ceste stať sa vysoko kvalifikovaným programátorom Java.

Postup v tomto blogu si vyžaduje určité úsilie, aby ste ich zvládli, ale výrazne zlepšia vaše každodenné skúsenosti s vývojom v prostredí Java. Vyhýbanie sa chybám je jednoduchšie, keď viete, ako správne aplikovať základné programovacie techniky Java, a sledovanie chýb je oveľa jednoduchšie, keď viete presne, čo sa deje s vašim kódom Java.

Ste pripravení začať ovládať základné koncepty programovania v jazyku Java? Potom začnime s naším prvým Java Challengerom!

Terminológia: Preťaženie metódy

Kvôli termínu preťaženie, vývojári si myslia, že táto technika preťaží systém, ale to nie je pravda. V programovaní preťaženie metódy znamená použitie rovnakého názvu metódy s rôznymi parametrami.

Čo je to preťaženie metódy?

Metóda preťaženia je programovacia technika, ktorá umožňuje vývojárom používať rovnaký názov metódy viackrát v tej istej triede, ale s rôznymi parametrami. V takom prípade hovoríme, že metóda je preťažená. Výpis 1 zobrazuje jednu metódu, ktorej parametre sa líšia počtom, typom a poradím.

Zoznam 1. Tri typy preťaženia metód

 Počet parametrov: verejná trieda Calculator {void spočítat (int číslo1, int číslo2) {} void spočítat (int číslo1, int číslo2, int číslo3) {}} Typ parametrov: verejná trieda Calculator {void vypočítať (int číslo1, int číslo2) ) {} výpočet neplatnosti (dvojité číslo1, dvojité číslo2) {}} Poradie parametrov: verejná trieda Calculator {výpočet prázdnoty (dvojité číslo1, int číslo2) {} výpočet neplatnosti (int číslo1, dvojité číslo2) {}} 

Metóda preťaženia a primitívne typy

V zozname 1 vidíte primitívne typy int a dvojitý. S týmito a ďalšími typmi budeme viac pracovať, preto si nájdite chvíľu a prečítajte si primitívne typy v Jave.

Tabuľka 1. Primitívne typy v Jave

TypRozsahPredvolenéVeľkosťUkážkové literály
boolean pravda alebo lož nepravdivé 1 bit pravda lož
bajt -128 .. 127 0 8 bitov 1, -90, 128
char Znak Unicode alebo 0 až 65 536 \ u0000 16 bitov 'a', '\ u0031', '\ 201', '\ n', 4
krátky -32,768 .. 32,767 0 16 bitov 1, 3, 720, 22,000
int -2,147,483,648 .. 2,147,483,647 0 32 bitov -2, -1, 0, 1, 9
dlho -9 223 372 036 854 775 808 až 9 223 372 036 854 775 807 0 64 bitov -4000L, -900L, 10L, 700L
plavák 3,40282347 x 1038, 1,40239846 x 10-45 0.0 32 bitov 1,67e200f, -1,57e-207f, 0,9f, 10,4F
dvojitý

1,7976931348623157 x 10308, 4,9406564584124654 x 10-324

 0.0 64 bitov 1.e700d, -123457e, 37e1d

Prečo by som mal používať preťaženie metód?

Preťaženie robí váš kód čistejším a ľahšie čitateľným a môže vám tiež pomôcť vyhnúť sa chybám vo vašich programoch.

Na rozdiel od výpisu 1 si predstavte program, kde ste mali viac vypočítať () metódy s názvami ako vypočítať1, vypočítať2, vypočítať3 . . . nie dobré, nie? Preťaženie vypočítať () metóda vám umožňuje používať rovnaký názov metódy a meniť iba to, čo je potrebné zmeniť: parametre. Je tiež veľmi ľahké nájsť preťažené metódy, pretože sú vo vašom kóde zoskupené.

Čo preťaženie nie je

Uvedomte si, že zmena názvu premennej nie je preťaženie. Nasledujúci kód sa nebude kompilovať:

 public class Calculator {void spočítať (int firstNumber, int secondNumber) {} void spočítať (int secondNumber, int thirdNumber) {}} 

Metódu tiež nemôžete preťažiť zmenou návratového typu v podpise metódy. Nasledujúci kód sa nebude kompilovať:

 public class Calculator {dvojitý výpočet (int číslo1, int číslo2) {návrat 0,0;} dlhý výpočet (int číslo1, int číslo2) {návrat 0;}} 

Preťaženie konštruktéra

Môžete preťažiť konštruktor rovnakým spôsobom, ako by ste použili metódu:

 public class Calculator {private int number1; súkromné ​​int číslo 2; verejná kalkulačka (int číslo1) {this.number1 = číslo1;} verejná kalkulačka (int číslo1, int číslo2) {this.number1 = číslo1; this.number2 = number2; }} 

Prijmite výzvu preťaženia metódy!

Ste pripravení na svoj prvý Java Challenger? Poďme zistiť!

Začnite dôkladnou kontrolou nasledujúceho kódu.

Zoznam 2. Výzva na preťaženie pokročilej metódy

 verejná trieda AdvancedOverloadingChallenge3 {statický reťazec x = ""; public static void main (String ... doYourBest) {executeAction (1); executeAction (1.0); executeAction (Double.valueOf ("5")); executeAction (1L); System.out.println (x); } static void executeAction (int ... var) {x + = "a"; } static void executeAction (Celé číslo var) {x + = "b"; } static void executeAction (Object var) {x + = "c"; } static void executeAction (krátke var) {x + = "d"; } static void executeAction (float var) {x + = "e"; } static void executeAction (dvojitá var) {x + = "f"; }} 

Dobre, skontrolovali ste kód. Aký je výstup?

  1. befe
  2. bfce
  3. efce
  4. aecf

Skontrolujte svoju odpoveď tu.

Čo sa práve stalo? Ako JVM zostavuje preťažené metódy

Aby ste pochopili, čo sa stalo v zozname 2, potrebujete vedieť niečo o tom, ako JVM kompiluje preťažené metódy.

V prvom rade je to JVM inteligentne lenivý: na vykonanie metódy bude vždy vynaložené najmenšie možné úsilie. Keď teda uvažujete o tom, ako JVM zvláda preťaženie, nezabudnite na tri dôležité techniky kompilátora:

  1. Rozšírenie
  2. Box (autoboxing a unboxing)
  3. Varargs

Ak ste sa s týmito tromi technikami nikdy nestretli, malo by vám ich objasniť niekoľko príkladov. Upozorňujeme, že JVM ich vykonáva v uvedenom poradí.

Tu je príklad rozširovanie:

 int primitiveIntNumber = 5; double primitiveDoubleNumber = primitiveIntNumber; 

Toto je poradie primitívnych typov, keď sú rozšírené:

Rafael del Nero

Tu je príklad autoboxing:

 int primitiveIntNumber = 7; Celé číslo wrapperIntegerNumber = primitiveIntNumber; 

Všimnite si, čo sa deje v zákulisí, keď sa kompiluje tento kód:

 Integer wrapperIntegerNumber = Integer.valueOf (primitiveIntNumber); 

A tu je príkladrozbaľovanie:

 Celé číslo wrapperIntegerNumber = 7; int primitiveIntNumber = wrapperIntegerNumber; 

Pri kompilácii tohto kódu sa deje v zákulisí:

 int primitiveIntNumber = wrapperIntegerNumber.intValue (); 

A tu je príklad varargs; poznač si to varargs je vždy posledný, ktorý sa má vykonať:

 vykonať (int ... čísla) {} 

Čo je to varargs?

Používa sa na variabilné argumenty, varargs je v podstate pole hodnôt špecifikovaných tromi bodkami (...) Môžeme prejsť akokoľvek veľa int čísla, ktoré chceme k tejto metóde.

Napríklad:

poprava (1,3,4,6,7,8,8,6,4,6,88 ...); // Mohli by sme pokračovať ... 

Varargs je veľmi praktický, pretože hodnoty je možné odovzdať priamo metóde. Ak by sme používali polia, museli by sme vytvoriť inštanciu poľa s hodnotami.

Rozšírenie: Praktický príklad

Keď odovzdáme číslo 1 priamo k executeAction metódou sa s ním JVM zaobchádza automaticky ako s int. Preto číslo nejde do čísla executeAction (krátka var) metóda.

Podobne, ak prekonáme číslo 1,0, JVM automaticky rozpozná toto číslo ako a dvojitý.

Číslo 1.0 by samozrejme mohlo byť aj a plavák, ale typ je vopred definovaný. Preto executeAction (dvojitá var) metóda je vyvolaná v zozname 2.

Keď použijeme Dvojitý typu obalu, existujú dve možnosti: buď číslo obalu možno rozbaliť na primitívny typ, alebo ho možno rozšíriť na Objekt. (Pamätajte, že každá trieda v jazyku Java rozširuje Objekt triedy.) V takom prípade sa JVM rozhodne obkľúčiť Dvojitý typ do Objekt pretože to vyžaduje menej úsilia, ako by to vyžadovalo rozbalenie, ako som už vysvetlil.

Posledné číslo, ktoré minieme, je 1L, a pretože sme tentokrát špecifikovali typ premennej, je to tak dlho.

Video výzva! Preťaženie metódy ladenia

Ladenie je jedným z najjednoduchších spôsobov, ako úplne absorbovať programovacie koncepty a zároveň vylepšiť váš kód. V tomto videu môžete sledovať, kým ladím a vysvetľujem výzvu preťaženia metódy:

Časté chyby s preťažením

Teraz ste už pravdepodobne prišli na to, že pri preťažení metódami to môže byť zložité, takže si zvážme niekoľko výziev, s ktorými sa pravdepodobne stretnete.

Autoboxovanie s obalmi

Java je programovací jazyk so silnými typmi, a keď používame autoboxovanie s obalmi, musíme mať na pamäti pár vecí. Nasledujúci kód sa nebude kompilovať:

 int primitiveIntNumber = 7; Dvojité wrapperNumber = primitiveIntNumber; 

Autoboxing bude fungovať iba s dvojitý zadajte, pretože to, čo sa stane, keď kompilujete tento kód, je rovnaké ako toto:

 Double number = Double.valueOf (primitiveIntNumber); 

Vyššie uvedený kód sa skompiluje. Prvýint typ bude rozšírený na dvojitý a potom sa to zaškatuľkuje Dvojitý. Ale pri autoboxe neexistuje rozšírenie typu a konštruktor z Double.valueOf dostane a dvojitý, nie int. V takom prípade by autoboxing fungoval, iba ak by sme použili obsadenie, napríklad takto:

 Double wrapperNumber = (double) primitiveIntNumber; 

Zapamätaj si toCelé číslo nemôže byť Dlhé a Plavák nemôže byť Dvojitý. Dedičstvo neexistuje. Každý z týchto typov -Celé číslo, Dlhé, Plaváka Double - jea Číslo a an Objekt.

Ak máte pochybnosti, nezabudnite, že počet obalových súborov je možné rozšíriť na Číslo alebo Objekt. (Oobaloch je možné preskúmať oveľa viac, ale to už nechám na iný príspevok.)

Napevno číselne typy čísel v JVM

Keď neurčíme typ na číslo, urobí to za nás JVM. Ak použijeme číslo 1 priamo v kóde, vytvorí ho JVM ako int. Ak sa pokúsite odovzdať 1 priamo metóde, ktorá prijíma a krátky, nebude sa kompilovať.

Napríklad:

 class Calculator {public static void main (String ... args) {// Táto invokácia tejto metódy sa nebude kompilovať // Áno, 1 môže byť char, short, byte, ale JVM ho vytvorí ako int count (1); } výpočet neplatnosti (krátke číslo) {}} 

Rovnaké pravidlo sa použije pri použití čísla 1,0; hoci by to mohlo byť a plavák, bude JVM považovať toto číslo za a dvojitý:

 class Calculator {public static void main (String ... args) {// Táto invokácia tejto metódy sa nebude kompilovať // Áno, 1 môže byť float, ale JVM ho vytvorí ako dvojitý výpočet (1.0); } výpočet neplatnosti (float number) {}} 

Ďalšou častou chybou je myslenie si, že Dvojitý alebo akýkoľvek iný typ obálky by bol vhodnejší pre metódu, ktorá prijíma a dvojitý. V skutočnosti to JVM vyžaduje menej úsilia rozširovať the Dvojitý zavinovačka do Objekt namiesto rozbalenia do a dvojitý primitívny typ.

Ak to zhrnieme, pri použití priamo v kóde Java bude 1 int a 1,0 bude dvojitý. Rozšírenie je najlenivejšia cesta k prevedeniu, na rad prichádza box alebo unboxing a posledná operácia bude vždy varargs.

Ako kuriózny fakt ste vedeli, že char typ prijíma čísla?

 char anyChar = 127; // Áno, je to zvláštne, ale kompiluje sa 

Čo treba pamätať na preťaženie

Preťaženie je veľmi účinná technika pre scenáre, kde potrebujete rovnaký názov metódy s rôznymi parametrami. Je to užitočná technika, pretože mať správny názov v kóde znamená veľký rozdiel pre čitateľnosť. Namiesto duplikovania metódy a pridania neporiadku do kódu ho môžete jednoducho preťažiť. Vďaka tomu bude váš kód čistý a ľahko čitateľný a zníži sa riziko, že duplicitné metódy rozbijú niektorú časť systému.

Na čo treba pamätať: Pri preťažení metódy vyvinie JVM najmenšie možné úsilie; toto je poradie najlenivejšej cesty k prevedeniu:

  • Prvá sa rozširuje
  • Druhým je box
  • Tretí je Varargs

Na čo si dať pozor: Z bezprostredného vyhlásenia čísla vzniknú zložité situácie: bude int a 1,0 bude dvojitý.

Pamätajte tiež, že tieto typy môžete výslovne deklarovať pomocou syntaxe 1F alebo 1f pre a plavák alebo 1D alebo 1d pre a dvojitý.

Týmto je ukončený náš prvý Java Challenger, ktorý predstavuje úlohu JVM pri preťažovaní metód. Je dôležité si uvedomiť, že JVM je vo svojej podstate lenivý a bude vždy nasledovať najlenivejšiu cestu k realizácii.

 

Odpovedať kľúč

Odpoveď na program Java Challenger v zozname 2 je: Možnosť 3. efce.

Viac informácií o preťažení metód v prostredí Java

  • Java 101: Triedy a objekty v Jave: Úvod do tried a objektov pre skutočných začiatočníkov vrátane krátkych častí o metódach a preťažení metód.
  • Java 101: Základné funkcie jazyka Java: Získajte viac informácií o tom, prečo je dôležité, že jazyk Java je silne písaný, a získajte úplné predstavenie primitívnych typov v jazyku Java.
  • Príliš veľa parametrov v metódach Java, časť 4: Preskúmajte obmedzenia a nevýhody preťaženia metód a ako ich možno napraviť integráciou vlastných typov a objektov parametrov.

Tento príbeh „Preťaženie metód v JVM“ pôvodne publikoval server JavaWorld.

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