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
Tipas | diapazonas | Numatytas | Dydis | Paž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čiuoti
1, 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?
- ištikti
- bfce
- efce
- 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:
- Plečiasi
- Boksas (autoboksas ir išpakavimas)
- 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:

Č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 - yra
a 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“.