Programmēšana

Metodes pārslodze JVM

Laipni lūdzam jaunajā Java izaicinātāji emuārs! Šis emuārs ir veltīts sarežģītiem Java programmēšanas jēdzieniem. Apgūstiet tos, un jums būs labs ceļš, lai kļūtu par augsti kvalificētu Java programmētāju.

Šī emuāra paņēmieni prasa zināmas pūles, lai tos apgūtu, taču tie ļoti mainīs jūsu ikdienas pieredzi kā Java izstrādātājam. Izvairīties no kļūdām ir vieglāk, ja zināt, kā pareizi pielietot Java galvenās programmēšanas metodes, un kļūdu izsekošana ir daudz vienkāršāka, ja precīzi zināt, kas notiek ar jūsu Java kodu.

Vai esat gatavs sākt apgūt Java programmēšanas pamatjēdzienus? Tad sāksim darbu ar mūsu pirmo Java Challenger!

Terminoloģija: metodes pārslodze

Termina dēļ pārslodze, izstrādātāji mēdz domāt, ka šī tehnika pārslogos sistēmu, taču tā nav taisnība. Programmēšanā metodes pārslodze nozīmē izmantot vienu un to pašu metodes nosaukumu ar dažādiem parametriem.

Kas ir metodes pārslodze?

Metodes pārslodze ir programmēšanas tehnika, kas ļauj izstrādātājiem vienā un tajā pašā klasē vairākas reizes izmantot vienu un to pašu metodes nosaukumu, bet ar dažādiem parametriem. Šajā gadījumā mēs sakām, ka metode ir pārslogota. 1. saraksts parāda vienu metodi, kuras parametri atšķiras pēc skaita, veida un secības.

Uzskaitīšana 1. Trīs veidu pārslodzes metodes

 Parametru skaits: publiskā klase Kalkulators {void aprēķināt (int numurs1, int skaitlis2) {} void aprēķināt (int numurs1, int skaitlis2, int skaitlis3) {}} Parametru veids: publiskā klase Kalkulators {void aprēķināt (int numurs1, int numurs2 ) {} void aprēķināt (dubultnumurs1, dubultnumurs2) {}} Parametru secība: publiskā klase Kalkulators {void aprēķināt (dubultnumurs1, intnumurs2) {} void aprēķins (int numurs1, dubultnumurs2) {}} 

Metodes pārslodze un primitīvi veidi

Sarakstā 1 jūs redzat primitīvos veidus int un dubultā. Mēs vairāk strādāsim ar šiem un citiem veidiem, tāpēc veltiet minūti, lai pārskatītu Java primitīvos veidus.

1. tabula. Primitīvie veidi Java

TipsDiapazonsNoklusējumsIzmērsBurtnieku piemērs
būla patiesība vai meli nepatiesa 1 bits patiess, nepatiess
baits -128 .. 127 0 8 biti 1, -90, 128
char Unicode rakstzīme vai no 0 līdz 65 536 \ u0000 16 biti 'a', '\ u0031', '\ 201', '\ n', 4
īss -32,768 .. 32,767 0 16 biti 1, 3, 720, 22,000
int -2,147,483,648 .. 2,147,483,647 0 32 biti -2, -1, 0, 1, 9
ilgi -9 223 372 036 854 775 808 līdz 9 223 372 036 854 775 807 0 64 biti -4000L, -900L, 10L, 700L
peldēt 3,40282347 x 1038, 1,40239846 x 10-45 0.0 32 biti 1,67e200f, -1,57e-207f, 0,9f, 10,4F
dubultā

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

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

Kāpēc man vajadzētu izmantot metodes pārslodzi?

Pārslodze padara kodu tīrāku un vieglāk lasāmu, un tas var arī palīdzēt izvairīties no kļūdām jūsu programmās.

Atšķirībā no 1. saraksta iedomājieties programmu, kurā jums bija vairāki aprēķināt () metodes ar nosaukumiem, piemēram, aprēķināt1, aprēķināt2, aprēķināt3 . . . nav labi, vai ne? Pārslodze aprēķināt () method ļauj izmantot to pašu metodes nosaukumu, vienlaikus mainot tikai to, kas jāmaina: parametrus. Ir arī ļoti viegli atrast pārslogotas metodes, jo tās ir sagrupētas jūsu kodā.

Kas nav pārslodze

Ņemiet vērā, ka mainīgā nosaukuma maiņa nav pārslodze. Šis kods netiks apkopots:

 public class Calculator {void aprēķināt (int pirmaisNumurs, int otraisnumurs) {} void aprēķināt (int otraisnumurs, int trešaisnumurs) {}} 

Jūs nevarat arī pārslogot metodi, mainot atgriešanās veidu metodes parakstā. Arī šis kods netiks apkopots:

 publiskā klase Kalkulators {divreiz aprēķiniet (int skaitlis1, int skaitlis2) {atdeve 0,0;} garš aprēķins (int skaitlis1, int skaitlis2) {atdeve 0;}} 

Konstruktora pārslodze

Konstruktoru var pārslogot tāpat kā metodi:

 public class Kalkulators {private int number1; privātais int numurs2; public Calculator (int number1) {this.number1 = number1;} public Calculator (int number1, int number2) {this.number1 = skaitlis1; this.number2 = skaitlis2; }} 

Pieņemiet metodi pārslodzes izaicinājums!

Vai esat gatavs savam pirmajam Java Challenger? Noskaidrosim!

Vispirms rūpīgi pārskatiet šo kodu.

Uzskaitījums 2. Izvērstās metodes pārslodzes izaicinājums

 publiskā klase AdvancedOverloadingChallenge3 {static String x = ""; public static void main (String ... doYourBest) {executeAction (1); izpildītAction (1.0); executeAction (Double.valueOf ("5")); izpildītAction (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 (īss var) {x + = "d"; } static void executeAction (float var) {x + = "e"; } static void executeAction (double var) {x + = "f"; }} 

Labi, jūs esat pārskatījis kodu. Kāda ir izeja?

  1. piemeklēt
  2. bfce
  3. efce
  4. aecf

Pārbaudiet savu atbildi šeit.

Kas tikko notika? Kā JVM apkopo pārslogotas metodes

Lai saprastu, kas notika 2. sarakstā, jums jāzina dažas lietas par to, kā JVM apkopo pārslogotas metodes.

Pirmkārt, JVM ir inteliģenti slinki: tā vienmēr pieliks pēc iespējas mazāk pūles, lai izpildītu metodi. Tādējādi, domājot par to, kā JVM apstrādā pārslodzi, ņemiet vērā trīs svarīgas kompilatora metodes:

  1. Paplašinās
  2. Bokss (autoboxing un unboxing)
  3. Varargs

Ja jūs nekad neesat saskāries ar šīm trim metodēm, dažiem tiem vajadzētu būt skaidrākiem. Ņemiet vērā, ka JVM tos izpilda dotajā secībā.

Šeit ir piemērs paplašināšanās:

 int primitīvsIntNumber = 5; double primitiveDoubleNumber = primitīvsIntNumber; 

Paplašinot, tā ir primitīvo tipu secība:

Rafaels del Nerons

Šeit ir piemērs autoboxing:

 int primitīvsIntNumber = 7; Integer wrapperIntegerNumber = primitīvsIntNumber; 

Ievērojiet, kas notiek aiz kadra, kad tiek apkopots šis kods:

 Integer wrapperIntegerNumber = Integer.valueOf (primitiveIntNumber); 

Un šeit ir piemērsunboxing:

 Integer wrapperIntegerNumber = 7; int primitiveIntNumber = wrapperIntegerNumber; 

Lūk, kas notiek aiz kadra, kad tiek apkopots šis kods:

 int primitiveIntNumber = wrapperIntegerNumber.intValue (); 

Un šeit ir piemērs varargs; pieraksti to varargs vienmēr tiek izpildīts pēdējais:

 izpildīt (int ... numuri) {} 

Kas ir varargs?

Izmanto mainīgajiem argumentiem, varargs būtībā ir trīs punktu noteikts masīvs (…) Mēs varam nodot garām tik daudz int numurus, kurus mēs vēlamies izmantot šai metodei.

Piemēram:

izpildīt (1,3,4,6,7,8,8,6,4,6,88 ...); // Mēs varētu turpināt ... 

Varargs ir ļoti ērts, jo vērtības var nodot tieši metodei. Ja mēs izmantotu masīvus, mums būtu jāpieliek masīvs ar vērtībām.

Paplašināšana: praktisks piemērs

Kad mēs nodosim numuru 1 tieši izpildītAction metodi, JVM to automātiski uztver kā int. Tāpēc numurs nenonāk pie executeAction (īss variants) metodi.

Līdzīgi, ja mēs izturēsim skaitli 1.0, JVM automātiski atpazīs šo skaitli kā a dubultā.

Protams, skaitlis 1.0 varētu būt arī a peldēt, bet veids ir iepriekš noteikts. Tāpēc executeAction (dubultā var) metode tiek izmantota 2. sarakstā.

Kad mēs izmantojam Dubultā iesaiņojuma veidam ir divas iespējas: vai nu iesaiņojuma numuru var noņemt kastē līdz primitīvam, vai arī to var paplašināt par Objekts. (Atcerieties, ka katra Java klase paplašina Objekts klase.) Tādā gadījumā JVM izvēlas paplašināt Dubultā ierakstiet an Objekts jo tas prasa mazāk pūļu, nekā to darītu, ja izskaidroju iepriekš.

Pēdējais mums nodotais skaitlis ir 1L, un tāpēc, ka šoreiz esam norādījuši mainīgā tipu, tas tā arī ir ilgi.

Video izaicinājums! Atkļūdošanas metodes pārslodze

Atkļūdošana ir viens no vienkāršākajiem veidiem, kā pilnībā absorbēt programmēšanas koncepcijas, vienlaikus uzlabojot arī kodu. Šajā videoklipā varat sekot līdzi, kamēr es atkļūdoju un izskaidroju metodes pārslodzes problēmu:

Biežas kļūdas ar pārslodzi

Tagad jūs, iespējams, esat sapratuši, ka ar metožu pārslodzi viss var kļūt sarežģīts, tāpēc ņemsim vērā dažas problēmas, ar kurām jūs, iespējams, saskarsieties.

Autoboksēšana ar iesaiņotājiem

Java ir ļoti tipizēta programmēšanas valoda, un, kad mēs izmantojam autoboxing ar iesaiņotājiem, mums jāpatur prātā dažas lietas. Pirmkārt, šāds kods netiks apkopots:

 int primitīvsIntNumber = 7; Double wrapperNumber = primitīvsIntNumber; 

Automātiskā boksēšana darbosies tikai ar dubultā tips, jo tas, kas notiek, apkopojot šo kodu, ir tāds pats kā šis:

 Divkāršs skaitlis = Double.valueOf (primitiveIntNumber); 

Iepriekšējais kods tiks apkopots. Pirmaisint tips tiks paplašināts līdz dubultā un tad tas tiks kastē Dubultā. Bet, pārvietojoties ar autoboksu, nav neviena veida paplašināšanas un konstruktora Double.valueOf saņems a dubultā, nevis an int. Šajā gadījumā autoboxing darbotos tikai tad, ja mēs izmantotu cast, piemēram:

 Double wrapperNumber = (dubultā) primitīvsIntNumber; 

Atcerieties, kaVesels skaitlis nevar būt Garš un Peldēt nevar būt Dubultā. Mantojuma nav. Katrs no šiem veidiem -Vesels skaitlis, Garš, Peldēt, un Double - ira Skaits un an Objekts.

Ja rodas šaubas, vienkārši atcerieties, ka iesaiņojuma numurus var palielināt līdz Skaits vai Objekts. (Ir daudz vairāk izpētīt par iesaiņotājiem, bet es to atstāšu citai ziņai.)

Cieti kodēti skaitļu veidi JVM

Kad skaitlim nenorādīsim veidu, JVM to izdarīs mūsu vietā. Ja kodā izmantosim tieši numuru 1, JVM to izveidos kā int. Ja mēģināt nodot 1 tieši metodei, kas saņem a īss, tas netiks apkopots.

Piemēram:

 klases kalkulators {public static void main (String… args) {// Šīs metodes izsaukums netiks apkopots // Jā, 1 varētu būt char, īss, baits, bet JVM to izveido kā int aprēķināt (1); } anulēt aprēķinu (īss skaitlis) {}} 

Tas pats noteikums tiks piemērots, lietojot skaitli 1.0; lai gan tas varētu būt a peldēt, JVM izturēsies pret šo skaitli kā dubultā:

 klases kalkulators {public static void main (String… args) {// Šīs metodes izsaukums netiks apkopots // Jā, 1 varētu būt peldošs, bet JVM to izveido kā divkāršu aprēķinu (1.0); } anulēt aprēķināt (peldošais skaitlis) {}} 

Vēl viena izplatīta kļūda ir domāt, ka Dubultā vai jebkurš cits iesaiņojuma veids būtu labāk piemērots metodei, kas saņem a dubultā. Patiesībā JVM ir jāpieliek mazāk pūļu paplašināties Dubultā iesaiņojums pie Objekts tā vietā, lai izpakotu to a dubultā primitīvs tips.

Rezumējot, ja to lieto tieši Java kodā, 1 būs int un 1.0 būs dubultā. Paplašināšana ir slinkākais ceļš uz izpildi, bokss vai unboxing nāk nākamais, un pēdējā darbība vienmēr būs varargs.

Kā kuriozu faktu, vai zinājāt, ka char tips pieņem skaitļus?

 char anyChar = 127; // Jā, tas ir dīvaini, bet tas apkopo 

Kas jāatceras par pārslodzi

Pārslodze ir ļoti spēcīgs paņēmiens scenārijiem, kur nepieciešams viens un tas pats metodes nosaukums ar dažādiem parametriem. Tas ir noderīgs paņēmiens, jo, ja kodā ir pareizs nosaukums, tas nozīmē liels lasāmības atšķirība. Tā vietā, lai dublētu metodi un pievienotu jucekli savam kodam, jūs varat to vienkārši pārslogot. Šādi rīkojoties, jūsu kods ir tīrs un viegli lasāms, un tas samazina risku, ka dublikātu metodes izjauks kādu sistēmas daļu.

Kas jāpatur prātā: Pārslogojot metodi, JVM pieliks visas iespējamās pūles; tā ir slinkākā ceļa izpildes kārtība:

  • Pirmais paplašinās
  • Otrais ir bokss
  • Trešais ir Varargs

Uz ko jāuzmanās: Sarežģītas situācijas radīsies, tieši deklarējot skaitli: 1 būs int un 1.0 būs dubultā.

Atcerieties arī, ka jūs varat skaidri deklarēt šos tipus, izmantojot a 1F vai 1f sintaksi peldēt vai 1D vai 1d a dubultā.

Tas noslēdz mūsu pirmo Java Challenger, iepazīstinot ar JVM lomu metožu pārslodzē. Ir svarīgi saprast, ka JVM pēc savas būtības ir slinks un vienmēr sekos slinkākajam ceļam uz izpildi.

 

Atbildes atslēga

Atbilde uz Java Challenger 2. sarakstā ir šāda: 3. iespēja. Efce.

Vairāk par metodes pārslodzi Java

  • Java 101: klases un objekti Java: īsts iesācēju ievads klasēs un objektos, ieskaitot īsas sadaļas par metodēm un metožu pārslodzi.
  • Java 101: elementāras Java valodas funkcijas: uzziniet vairāk par to, kāpēc ir svarīgi, ka Java ir stingri rakstīta valoda, un iegūstiet pilnu ievadu par primitīviem Java veidiem.
  • Pārāk daudz parametru Java metodēs, 4. daļa: Izpētiet metožu pārslodzes ierobežojumus un trūkumus un to, kā tos var novērst, integrējot pielāgotos tipus un parametru objektus.

Šo stāstu "Metodes pārslodze JVM" sākotnēji publicēja JavaWorld.

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