Programavimas

Metodo perkrova JVM

Sveiki atvykę į naująjį „Java Challengers“ dienoraštis! Šis tinklaraštis skirtas sudėtingoms „Java“ programavimo koncepcijoms. Įvaldykite juos ir galėsite sėkmingai tapti aukštos kvalifikacijos „Java“ programuotoju.

Šio tinklaraščio metodus reikia šiek tiek pasisavinti, tačiau jie labai pakeis jūsų, kaip „Java“ kūrėjo, kasdienę patirtį. Išvengti klaidų yra lengviau, kai mokate tinkamai pritaikyti pagrindines „Java“ programavimo technikas, o klaidų sekimas yra daug lengvesnis, kai tiksliai žinote, kas vyksta jūsų „Java“ kode.

Ar esate pasirengęs pradėti įvaldyti pagrindines „Java“ programavimo koncepcijas? Tada pradėkime nuo pirmojo „Java Challenger“!

Terminija: metodo perkrova

Dėl termino perkrova, kūrėjai linkę manyti, kad ši technika perkraus sistemą, tačiau tai netiesa. Programuodami, metodo perkrova reiškia naudoti tą patį metodo pavadinimą su skirtingais parametrais.

Kas yra metodo perkrova?

Metodo perkrova yra programavimo technika, leidžianti kūrėjams naudoti tą patį metodo pavadinimą kelis kartus toje pačioje klasėje, tačiau su skirtingais parametrais. Šiuo atveju mes sakome, kad metodas yra perkrautas. 1 sąraše rodomas vienas metodas, kurio parametrai skiriasi skaičiumi, tipu ir tvarka.

Išvardinimas 1. Trys metodų perkrovos tipai

 Parametrų skaičius: viešosios klasės skaičiuoklė {void apskaičiuoti (int skaičius1, int skaičius2) {} void apskaičiuoti (int skaičius1, int skaičius2, int skaičius3) {}} Parametrų tipas: viešosios klasės skaičiuoklė {negaliojantis apskaičiuoti (int skaičius1, int skaičius2) ) {} void apskaičiuoti (dvigubas skaičius1, dvigubas skaičius2) {}} Parametrų tvarka: viešosios klasės skaičiuoklė {void apskaičiuoti (dvigubas skaičius1, int skaičius2) {} void apskaičiuoti (int skaičius1, dvigubas skaičius2) {}} 

Metodo perkrova ir primityvūs tipai

1 sąraše matote primityvius tipus tarpt ir dvigubai. Daugiau dirbsime su šiais ir kitais tipais, todėl skirkite minutę, kad peržiūrėtumėte primityvius „Java“ tipus.

1 lentelė. Pirminiai „Java“ tipai

TipasdiapazonasNumatytasDydisPažodinių pavyzdžiai
loginis tiesa ar melas melagingas 1 bit tiesa, melas
baitas -128 .. 127 0 8 bitai 1, -90, 128
char „Unicode“ simbolis arba nuo 0 iki 65 536 \ u0000 16 bitų „a“, „\ u0031“, „\ 201“, „\ n“, 4
trumpas -32,768 .. 32,767 0 16 bitų 1, 3, 720, 22,000
tarpt -2,147,483,648 .. 2,147,483,647 0 32 bitai -2, -1, 0, 1, 9
ilgas -9 223 372 036 854 775 808 - 9 223 372 036 854 775 807 0 64 bitai -4000L, -900L, 10L, 700L
plūdė 3,40282347 x 1038, 1,40239846 x 10-45 0.0 32 bitai 1,67e200f, -1,57e-207f, 0,9f, 10,4F
dvigubai

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

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

Kodėl turėčiau naudoti metodo perkrovą?

Perkrovimas daro jūsų kodą švaresnį ir lengviau skaitomą, taip pat gali padėti išvengti programų klaidų.

Priešingai nei 1 sąraše, įsivaizduokite programą, kurioje turėjote kelis apskaičiuoti() metodai su pavadinimais kaip apskaičiuoti1, apskaičiuoti2, apskaičiuoti3 . . . nėra gerai, tiesa? Perkraunama apskaičiuoti() metodas leidžia naudoti tą patį metodo pavadinimą, keičiant tik tai, ką reikia pakeisti: parametrus. Taip pat labai lengva rasti perkrautus metodus, nes jie yra sugrupuoti į jūsų kodą.

Kas nėra perkrova

Atminkite, kad kintamojo pavadinimo keitimas nėra perkrova. Šis kodas nebus sudarytas:

 public class Calculator {void apskaičiuoti (int firstNumber, int secondNumber) {} void apskaičiuoti (int secondNumber, int thirdNumber) {}} 

Taip pat negalite perkrauti metodo, pakeisdami grąžinimo tipą metodo paraše. Šis kodas taip pat nebus kompiliuojamas:

 viešosios klasės skaičiuoklė {dvigubai apskaičiuoti (int skaičius1, int skaičius2) {grąžinti 0,0;} ilgas apskaičiuoti (int skaičius1, int skaičius2) {grąžinti 0;}} 

Konstruktoriaus perkrova

Galite perkrauti konstruktorių taip pat, kaip ir metodą:

 viešosios klasės skaičiuoklė {privatus int numeris1; privatus int numeris2; public Calculator (int number1) {this.number1 = number1;} public Calculator (int number1, int number2) {this.number1 = skaičius1; this.number2 = skaičius2; }} 

Pasinaudokite perkrovos metodo iššūkiu!

Ar esate pasirengęs savo pirmajam „Java Challenger“? Išsiaiškinkime!

Pirmiausia atidžiai peržiūrėkite šį kodą.

Sąrašas 2. Išplėstinio metodo perkrovos iššūkis

 viešoji klasė „AdvancedOverloadingChallenge3“ {statinė eilutė x = ""; public static void main (String ... doYourBest) {executeAction (1); executeAction (1.0); executeAction (Double.valueOf ("5")); vykdyti „Action“ (1L); System.out.println (x); } static void executeAction (int ... var) {x + = "a"; } static void executeAction (Integer var) {x + = "b"; } static void executeAction (Objekto var) {x + = "c"; } static void executeAction (trumpas var) {x + = "d"; } static void executeAction (float var) {x + = "e"; } static void executeAction (dvigubas var) {x + = "f"; }} 

Gerai, jūs peržiūrėjote kodą. Kokia išvestis?

  1. ištikti
  2. bfce
  3. efce
  4. aecf

Patikrinkite savo atsakymą čia.

Kas ką tik nutiko? Kaip JVM rengia perkrautus metodus

Norėdami suprasti, kas įvyko 2 sąraše, turite žinoti keletą dalykų, kaip JVM rengia perkrautus metodus.

Visų pirma, JVM yra protingai tingus: metodas bus visada dedamas kuo mažiau. Taigi, galvodami apie tai, kaip JVM tvarko perkrovą, turėkite omenyje tris svarbius kompiliatoriaus metodus:

  1. Plečiasi
  2. Boksas (autoboksas ir išpakavimas)
  3. Varargas

Jei niekada nesate susidūrę su šiomis trimis technikomis, keli pavyzdžiai turėtų padėti jas išaiškinti. Atkreipkite dėmesį, kad JVM juos vykdo duota tvarka.

Čia yra pavyzdys platėjantis:

 int primityvusIntNumber = 5; dvigubas primitiveDoubleNumber = primitiveIntNumber; 

Tai yra primityvių tipų tvarka, kai ji yra išplėsta:

Rafaelis del Neronas

Čia yra pavyzdys autoboxing:

 int primityvusIntNumber = 7; Sveikas skaičius wrapperIntegerNumber = primityvusIntNumber; 

Atkreipkite dėmesį, kas vyksta užkulisiuose, kai yra sudaromas šis kodas:

 Sveikas skaičius wrapperIntegerNumber = Integer.valueOf (primitiveIntNumber); 

Ir čia yra pavyzdysišpakavimas:

 Sveikasis skaičius suvyniotasIntegerNumber = 7; int primityvusIntNumber = wrapperIntegerNumber; 

Štai kas vyksta užkulisiuose, kai yra sudaromas šis kodas:

 int primitiveIntNumber = wrapperIntegerNumber.intValue (); 

Ir čia yra pavyzdys varargas; Prisimink tai varargas visada įvykdoma paskutinė:

 vykdyti (int… numeriai) {} 

Kas yra varargas?

Naudojamas kintamiesiems argumentams, varargas iš esmės yra trijų taškų nurodytų verčių masyvas (…) Kad ir kaip daug, galime perduoti tarpt skaičiai, kuriuos norime naudoti šį metodą.

Pavyzdžiui:

vykdyti (1,3,4,6,7,8,8,6,4,6,88 ...); // Galėtume tęsti ... 

„Varargs“ yra labai patogu, nes reikšmes galima tiesiogiai perduoti metodui. Jei naudotume masyvus, turėtume masyvą iš karto instaliuoti su reikšmėmis.

Plėtimas: praktinis pavyzdys

Kai skaičių 1 perduosime tiesiai į vykdyti veiksmą metodas, JVM automatiškai traktuoja jį kaip tarpt. Štai kodėl skaičius nepatenka į „executeAction“ (trumpas variantas) metodas.

Panašiai, jei mes perduosime skaičių 1.0, JVM automatiškai atpažins tą skaičių kaip a dvigubai.

Žinoma, skaičius 1,0 taip pat galėtų būti a plūdė, bet tipas iš anksto nustatytas. Štai kodėl executeAction (dvigubas var) metodas yra naudojamas 2 sąraše.

Kai mes naudojame Dvigubai įvyniojimo tipo, yra dvi galimybės: arba įvyniojimo numerį galima ištrinti iki primityvaus tipo, arba jį galima išplėsti į Objektas. (Atminkite, kad kiekviena „Java“ klasė pratęsia Objektas klasė.) Tokiu atveju JVM nusprendžia išplėsti Dvigubai įveskite į Objektas nes tam reikia mažiau pastangų nei išpakuoti, kaip paaiškinau anksčiau.

Paskutinis skaičius, kurį praleidome, yra 1L, ir kadangi šį kartą nurodėme kintamojo tipą, jis yra ilgas.

Vaizdo iššūkis! Derinimo metodo perkrovimas

Derinimas yra vienas iš paprasčiausių būdų visiškai įsisavinti programavimo koncepcijas, kartu tobulinant kodą. Šiame vaizdo įraše galite sekti, kol aš derinu ir paaiškinu metodo perkrovos iššūkį:

Dažniausios perkrovos klaidos

Dabar jau tikriausiai supratote, kad dėl per didelio metodo gali būti keblu, todėl apsvarstykime keletą iššūkių, su kuriais greičiausiai susidursite.

Autobokso su pakuotėmis

„Java“ yra labai tipiška programavimo kalba, ir kai mes naudojame automatinį naršymą su įvyniotojais, turime atsiminti keletą dalykų. Viena vertus, šis kodas nebus kompiliuojamas:

 int primityvusIntNumber = 7; Dvigubas wrapperNumber = primityvusIntNumber; 

Autobokso funkcija veiks tik su dvigubai įveskite, nes tai, kas atsitinka, kai sudarote šį kodą, yra tas pats, kas nurodyta toliau:

 Dvigubas skaičius = Double.valueOf (primitiveIntNumber); 

Aukščiau pateiktas kodas bus sudarytas. Pirmastarpt tipas bus išplėstas iki dvigubai ir tada jis bus dėžėje Dvigubai. Bet kai vyksta greitkelis, nėra jokio tipo išplėtimo ir konstruktoriaus Double.valueOf gaus a dvigubai, o ne an tarpt. Šiuo atveju autoboksas veiktų tik tuo atveju, jei pritaikytume „cast“, taip:

 Double wrapperNumber = (dvigubas) primityvusIntNumber; 

Prisiminti, kadSveikasis skaičius negali būti Ilgas ir Plūdė negali būti Dvigubai. Paveldėjimo nėra. Kiekvienas iš šių tipų -Sveikasis skaičius, Ilgas, Plūdėir Dvigubas - yraa Skaičius ir an Objektas.

Jei kyla abejonių, tiesiog nepamirškite, kad pakavimo numerius galima išplėsti iki Skaičius arba Objektas. (Daug daugiau reikia ištirti apie vyniotuvus, bet aš paliksiu tai kitam įrašui.)

Tvirtai užkoduoti skaičių tipai JVM

Kai numeriui nenurodome tipo, JVM tai padarys už mus. Jei kode naudosime skaičių 1, JVM sukurs jį kaip tarpt. Jei bandysite perduoti 1 tiesiogiai metodui, kuris gauna a trumpas, jis nesudarys.

Pavyzdžiui:

 klasės skaičiuoklė {public static void main (String… args) {// Šis metodo iškvietimas nebus kompiliuojamas // Taip, 1 gali būti char, trumpas, baitas, bet JVM sukuria jį kaip int apskaičiuoti (1); } negaliojantis apskaičiuoti (trumpas skaičius) {}} 

Ta pati taisyklė bus taikoma naudojant skaičių 1,0; nors tai galėtų būti a plūdė, JVM šį skaičių traktuos kaip a dvigubai:

 klasės skaičiuoklė {public static void main (String… args) {// Šio metodo iškvietimas nebus kompiliuojamas // Taip, 1 galėtų būti plūduriuojantis, bet JVM sukuria jį kaip dvigubą skaičiavimą (1.0); } negaliojantis apskaičiuoti (plūduriuojantis skaičius) {}} 

Kita dažna klaida yra manyti, kad Dvigubai ar bet kuris kitas apvalkalo tipas geriau tiktų metodui, kuris gauna a dvigubai. Tiesą sakant, JVM reikia mažiau pastangų praplatėti Dvigubai įvyniojimas į Objektas užuot išpakavę jį į a dvigubai primityvus tipas.

Apibendrinant galima teigti, kad tiesiogiai naudojant „Java“ kodą 1 bus tarpt ir 1.0 bus dvigubai. Išsiplėtimas yra tingiausias kelias į vykdymą, boksas ar išpakavimas vyksta toliau, o paskutinė operacija bus visada varargas.

Kaip įdomus faktas, ar žinojote, kad char tipas priima numerius?

 char anyChar = 127; // Taip, tai keista, bet tai sudaro 

Ką atsiminti apie perkrovą

Perkrovimas yra labai galinga scenarijų technika, kai jums reikia to paties metodo pavadinimo su skirtingais parametrais. Tai naudinga technika, nes turint teisingą vardą kode, galite: didelis skaitomumo skirtumas. Užuot dubliavę metodą ir pridėję netvarkos prie savo kodo, galite paprasčiausiai jį perkrauti. Tai padarius jūsų kodas bus švarus ir lengvai skaitomas, o tai sumažina riziką, kad pasikartojantys metodai sugadins kai kurią sistemos dalį.

Ką reikėtų nepamiršti: Perkraunant metodą, JVM dės kuo mažiau pastangų; tai yra tingiausio įvykdymo kelio tvarka:

  • Pirmasis plečiasi
  • Antra yra boksas
  • Trečias yra Varargas

Ko reikia saugotis: Keblios situacijos susidarys tiesiogiai deklaravus skaičių: 1 bus tarpt ir 1.0 bus dvigubai.

Taip pat atminkite, kad galite aiškiai deklaruoti šiuos tipus naudodami 1F arba 1f sintaksę a plūdė arba 1D arba 1d a dvigubai.

Tai užbaigia mūsų pirmąjį „Java Challenger“, pristatantį JVM vaidmenį perkraunant metodą. Svarbu suvokti, kad JVM iš prigimties yra tingus ir visada eis tingiausiu keliu.

 

Atsakymo raktas

Atsakymas į „Java Challenger“ 2 sąraše yra: 3 variantas.

Daugiau apie metodo perkrovą „Java“

  • „Java 101“: „Java“ klasės ir objektai: tikras pradedančiųjų įvadas į klases ir objektus, įskaitant trumpus skyrius apie metodus ir metodų perkrovimą.
  • „Java 101“: pagrindinės „Java“ kalbos ypatybės: sužinokite daugiau apie tai, kodėl svarbu, kad „Java“ yra griežtai įvesta kalba, ir išsamiai susipažinkite su primityviais „Java“ tipais.
  • Per daug parametrų „Java“ metoduose. 4 dalis. Išnagrinėkite metodo perkrovos apribojimus ir trūkumus bei kaip juos galima pašalinti integruojant pasirinktinius tipus ir parametrų objektus.

Šią istoriją „Metodo perkrova JVM“ iš pradžių paskelbė „JavaWorld“.