Programiranje

Preobremenitev metode v JVM

Dobrodošli v novem Java izzivalci blog! Ta blog je posvečen izzivnim konceptom v programiranju Java. Obvladajte jih in na dobri poti boste postali visoko usposobljeni programer Java.

Tehnike v tem blogu se sicer nekoliko potrudite, vendar bodo zelo vplivale na vaše vsakodnevne izkušnje kot razvijalec Jave. Izogniti se napakam je lažje, če veste, kako pravilno uporabiti osnovne tehnike programiranja Java, sledenje napakam pa je veliko lažje, ko natančno veste, kaj se dogaja na vaši kodi Java.

Ste pripravljeni začeti obvladovati ključne koncepte v programiranju Java? Potem začnimo z našim prvim Java Challengerjem!

Terminologija: Preobremenitev metode

Zaradi izraza preobremenitev, razvijalci ponavadi mislijo, da bo ta tehnika preobremenila sistem, vendar to ni res. Pri programiranju preobremenitev metode pomeni uporabo istega imena metode z različnimi parametri.

Kaj je preobremenitev metode?

Preobremenitev metode je programska tehnika, ki razvijalcem omogoča, da isto ime metode večkrat uporabljajo v istem razredu, vendar z različnimi parametri. V tem primeru pravimo, da je metoda preobremenjena. Seznam 1 prikazuje posamezno metodo, katere parametri se razlikujejo po številu, vrsti in vrstnem redu.

Seznam 1. Tri vrste preobremenitve metode

 Število parametrov: kalkulator javnega razreda {void izračun (int število1, int število2) {} void izračuna (int število1, int število2, int število3) {}} Vrsta parametrov: javni razred kalkulator {void izračun (int število1, int število2 ) {} neveljavno izračunavanje (dvojno število1, dvojno število2) {}} Vrstni red parametrov: javni razred Kalkulator {void izračunaj (dvojno število1, int število2) {} neveljavno izračunaj (int število1, dvojno število2) {}} 

Preobremenitev metode in primitivni tipi

V seznamu 1 vidite primitivne tipe int in dvojno. Delali bomo več s temi in drugimi vrstami, zato si vzemite minuto za pregled primitivnih vrst v Javi.

Tabela 1. Primitivni tipi v Javi

TipDosegPrivzetoVelikostPrimeri dobesednih besed
logično pravilno ali napačno napačno 1 bit pravilno napačno
bajt -128 .. 127 0 8 bitov 1, -90, 128
char Znak Unicode ali od 0 do 65.536 \ u0000 16 bitov 'a', '\ u0031', '\ 201', '\ n', 4
kratek -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
dolga -9.223.372.036.854.775.808 do 9.223.372.036.854.775.807 0 64 bitov -4000L, -900L, 10L, 700L
plovec 3,40282347 x 1038, 1,40239846 x 10-45 0.0 32 bitov 1,67e200f, -1,57e-207f, .9f, 10,4F
dvojno

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

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

Zakaj naj uporabljam preobremenitev metode?

Zaradi preobremenitve je koda čistejša in lažja za branje, prav tako pa vam lahko pomaga, da se izognete napakam v svojih programih.

V nasprotju s seznamom 1 si predstavljajte program, v katerem ste imeli več izračunaj () metode z imeni kot izračunajte1, izračunaj2, izračunaj3 . . . ni dobro, kajne? Preobremenitev izračunaj () metoda vam omogoča, da uporabite isto ime metode, medtem ko spreminjate le tisto, kar je treba spremeniti: parametre. Prav tako je zelo enostavno najti preobremenjene metode, ker so združene v vaši kodi.

Česar preobremenitev ni

Zavedajte se, da spreminjanje imena spremenljivke ni preobremenitev. Naslednja koda ne bo prevedena:

 kalkulator javnega razreda {void izračunaj (int firstNumber, int secondNumber) {} neveljavno izračunaj (int secondNumber, int thirdNumber) {}} 

Metode tudi ne morete preobremeniti s spreminjanjem vrste vrnitve v podpisu metode. Tudi naslednja koda ne bo prevedena:

 javni razred Kalkulator {dvojni izračun (int število1, int število2) {vrnitev 0,0;} dolg izračun (int število1, int število2) {vrnitev 0;}} 

Preobremenitev konstruktorja

Konstruktor lahko preobremenite na enak način kot metodo:

 javni razred Kalkulator {private int number1; zasebna int številka2; javni kalkulator (int number1) {this.number1 = number1;} javni kalkulator (int number1, int number2) {this.number1 = number1; to.številka2 = število2; }} 

Sprejmite izziv preobremenitve metode!

Ste pripravljeni na svoj prvi Java Challenger? Pa ugotovimo!

Najprej natančno preglejte naslednjo kodo.

Seznam 2. Izziv za preobremenitev napredne metode

 javni razred AdvancedOverloadingChallenge3 {static String x = ""; javna statična 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 (Integer var) {x + = "b"; } static void executeAction (Object var) {x + = "c"; } static void executeAction (kratka var) {x + = "d"; } static void executeAction (float var) {x + = "e"; } static void executeAction (dvojna var) {x + = "f"; }} 

V redu, pregledali ste kodo. Kakšen je rezultat?

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

Odgovor preverite tukaj.

Kaj se je pravkar zgodilo? Kako JVM prevaja preobremenjene metode

Da bi razumeli, kaj se je zgodilo v seznamu 2, morate vedeti nekaj o tem, kako JVM prevaja preobremenjene metode.

Prvič, JVM je inteligentno len: za izvajanje metode se bo vedno potrudil najmanj. Ko razmišljate o tem, kako JVM obvladuje preobremenitev, upoštevajte tri pomembne tehnike prevajalnika:

  1. Širjenje
  2. Boks (avtoboksanje in odpakiranje)
  3. Varargi

Če se teh treh tehnik še niste srečali, bi vam nekaj primerov pomagalo razjasniti. Upoštevajte, da jih JVM izvrši v danem vrstnem redu.

Tu je primer razširitev:

 int primitiveIntNumber = 5; dvojno primitiveDoubleNumber = primitiveIntNumber; 

Ta vrstni red primitivnih vrst je razširjen:

Rafael del Nero

Tu je primer avtoboks:

 int primitiveIntNumber = 7; Integer wrapperIntegerNumber = primitiveIntNumber; 

Upoštevajte, kaj se zgodi v ozadju, ko je ta koda sestavljena:

 Integer wrapperIntegerNumber = Integer.valueOf (primitiveIntNumber); 

In tukaj je primerrazpakiranje:

 Integer wrapperIntegerNumber = 7; int primitiveIntNumber = wrapperIntegerNumber; 

Tu se dogaja v ozadju, ko je ta koda sestavljena:

 int primitiveIntNumber = wrapperIntegerNumber.intValue (); 

In tukaj je primer varargi; Upoštevajte to varargi je vedno zadnji, ki se izvede:

 izvrši (int… številke) {} 

Kaj so varargi?

Uporablja se za spremenljive argumente, varargi je v bistvu niz vrednosti, določenih s tremi pikami (...) Lahko jih prenesemo toliko int števila, ki jih želimo tej metodi.

Na primer:

izvrši (1,3,4,6,7,8,8,6,4,6,88 ...); // Lahko bi nadaljevali ... 

Varargs je zelo priročen, ker se lahko vrednosti posredujejo neposredno v metodo. Če bi uporabljali polja, bi morali matriko primeriti z vrednostmi.

Širjenje: Praktičen primer

Ko prenesemo številko 1 neposredno na executeAction JVM samodejno obravnava kot int. Zato številka ne gre na executeAction (kratka var) metoda.

Če podamo številko 1.0, JVM to številko samodejno prepozna kot a dvojno.

Seveda bi lahko bila številka 1.0 tudi plovec, vendar je vrsta vnaprej določena. Zato executeAction (dvojna var) metoda je navedena v seznamu 2.

Ko uporabljamo Dvojno tipu ovoja, obstajata dve možnosti: bodisi številko ovoja je mogoče odstraniti iz primitivnega tipa ali pa jo razširiti v Predmet. (Ne pozabite, da vsak razred v Javi razširja Predmet class.) V tem primeru se JVM odloči razširiti Dvojno vnesite v Predmet ker zahteva manj napora kot razpakiranje, kot sem že razložil.

Zadnja številka, ki jo posredujemo, je 1L in ker smo tokrat določili vrsto spremenljivke, je dolga.

Video izziv! Preobremenitev metode odpravljanja napak

Odpravljanje napak je eden najlažjih načinov za popolno absorpcijo konceptov programiranja, hkrati pa izboljšate kodo. V tem videoposnetku lahko spremljate postopek razhroščevanja in razložite izziv preobremenitve metode:

Pogoste napake pri preobremenitvi

Do zdaj ste verjetno že ugotovili, da se lahko s preobremenjenostjo metod zaplete, zato si oglejmo nekaj izzivov, s katerimi se boste verjetno srečali.

Avtoboks z ovoji

Java je močno natipkan programski jezik in pri uporabi samodejnega boksanja z zavitki moramo upoštevati nekaj stvari. Za začetek se naslednja koda ne bo prevedla:

 int primitiveIntNumber = 7; Double wrapperNumber = primitiveIntNumber; 

Autoboxing bo deloval samo z dvojno type, kajti zgodi se, ko prevedete to kodo, enako kot naslednje:

 Dvojna številka = Double.valueOf (primitiveIntNumber); 

Zgornja koda bo sestavljena. Prviint vrsta bo razširjena na dvojno in potem bo v boks Dvojno. Toda pri samodejnem zaboju ni razširitve tipa in konstruktor iz Double.valueOf bo prejel a dvojno, ne int. V tem primeru bi samodejni zaboj deloval le, če bi uporabili igralsko zasedbo, takole:

 Double wrapperNumber = (dvojno) primitiveIntNumber; 

Zapomni si toCelo število ne more biti dolga in Float ne more biti Dvojno. Dedovanja ni. Vsaka od teh vrst -Celo število, dolga, Float, in Dvojna - jea Številka in an Predmet.

Če ste v dvomih, samo ne pozabite, da je mogoče številke ovojnic razširiti na Številka ali Predmet. (O zavitkih je treba raziskati še veliko več, vendar ga bom pustil za drugo objavo.)

Trdo kodirane vrste številk v JVM

Ko številki ne določimo vrste, bo to naredil JVM namesto nas. Če uporabimo številko 1 neposredno v kodi, jo bo JVM ustvaril kot int. Če poskusite prenesti 1 neposredno metodi, ki prejema datoteko kratek, se ne bo prevedel.

Na primer:

 class Calculator {public static void main (String ... args) {// Ta klic metode se ne bo prevedel // Da, 1 je lahko char, kratek, bajt, vendar ga JVM ustvari kot int izračun (1); } neveljaven izračun (kratka številka) {}} 

Enako pravilo bo veljalo pri uporabi številke 1.0; čeprav bi lahko bil plovec, bo JVM to številko obravnaval kot dvojno:

 razred Kalkulator {public static void main (String… args) {// Ta klic metode se ne bo prevedel // Da, 1 je lahko float, vendar ga JVM ustvari kot dvojni izračun (1.0); } neveljaven izračun (float številka) {}} 

Druga pogosta napaka je misel, da Dvojno ali katera koli druga vrsta ovitka bi bila bolj primerna za metodo, ki prejema a dvojno. Pravzaprav JVM potrebuje manj napora razširiti Dvojno ovoj v Predmet namesto da bi ga odpakirali v dvojno primitivni tip.

Če povzamemo, pri neposredni uporabi v kodi Java bo 1 int in 1.0 bo dvojno. Razširitev je najbolj lena pot do izvedbe, boksanje ali razpakiranje je na vrsti in zadnja operacija bo vedno varargi.

Kot nenavadno dejstvo, ali ste vedeli, da char vrsta sprejema številke?

 char anyChar = 127; // Da, to je čudno, vendar se prevaja 

Kaj si je treba zapomniti pri preobremenitvi

Preobremenitev je zelo zmogljiva tehnika za scenarije, kjer potrebujete isto ime metode z različnimi parametri. To je uporabna tehnika, saj je ob pravilnem imenu v kodi znak velik razlika za berljivost. Namesto da bi podvojili metodo in kodi dodali nered, jo lahko preprosto preobremenite. S tem boste ohranili svojo kodo čisto in enostavno za branje ter zmanjšali tveganje, da bodo podvojene metode zlomile del sistema.

Kaj je treba upoštevati: Pri preobremenitvi metode se bo JVM potrudil čim manj; to je vrstni red najbolj lene poti do izvedbe:

  • Najprej se širi
  • Drugi je boks
  • Tretji je Varargs

Na kaj paziti: Zapletene situacije se bodo pojavile pri neposredni prijavi številke: 1 bo int in 1.0 bo dvojno.

Ne pozabite tudi, da lahko te vrste izrecno deklarirate s sintakso 1F ali 1f za a plovec ali 1D ali 1d za a dvojno.

S tem smo zaključili naš prvi Java Challenger in predstavili vlogo JVM pri preobremenitvi metod. Pomembno je vedeti, da je JVM po naravi len in bo vedno sledil najbolj leni poti do usmrtitve.

 

Tipka za odgovor

Odgovor na Java Challenger v seznamu 2 je: Možnost 3. efce.

Več o preobremenitvi metode v Javi

  • Java 101: Razredi in predmeti v Javi: resnični začetniški uvod v razrede in predmete, vključno s kratkimi odseki o metodah in preobremenitvi metod.
  • Java 101: Osnovne značilnosti jezika Java: Preberite več o tem, zakaj je pomembno, da je Java močno tipkan jezik, in si oglejte popoln uvod v primitivne vrste v Javi.
  • Preveč parametrov v metodah Java, 4. del: Raziščite omejitve in slabosti preobremenitve metode in kako jih je mogoče odpraviti z vključevanjem vrst po meri in objektov parametrov.

To zgodbo, "Preobremenitev metode v JVM", je prvotno objavil JavaWorld.

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