Pass-By-Value som en parameteroverføringsmekanisme i Java

1. Introduksjon

De to vanligste måtene å overføre argumenter til metoder er "forbipasserende verdi" og "forbipasserende referanse". Ulike programmeringsspråk bruker disse konseptene på forskjellige måter. Når det gjelder Java, er alt strengt Pass-by-verdi.

I denne opplæringen skal vi illustrere hvordan Java sender argumenter for forskjellige typer.

2. Pass-by-Value vs Pass-by-Reference

La oss starte med noen av de forskjellige mekanismene for å overføre parametere til funksjoner:

  • verdi
  • henvisning
  • resultat
  • verdi-resultat
  • Navn

De to vanligste mekanismene i moderne programmeringsspråk er "Pass-by-Value" og "Pass-by-Reference". Før vi fortsetter, la oss diskutere disse først:

2.1. Pass-by-verdi

Når en parameter er forbipasseringsverdi, fungerer den som ringer og callee-metoden på to forskjellige variabler som er kopier av hverandre. Eventuelle endringer i den ene variabelen endrer ikke den andre.

Det betyr at mens du kaller en metode, parametere sendt til callee-metoden vil være kloner av originale parametere. Enhver endring utført i callee-metoden vil ikke ha noen innvirkning på de opprinnelige parameterne i anropsmetoden.

2.2. Pass-by-Reference

Når en parameter er forbipasserende, fungerer innringeren og callee på det samme objektet.

Det betyr at når en variabel er forbipasserende, den unike identifikatoren til objektet sendes til metoden. Eventuelle endringer i parameterens instansmedlemmer vil føre til at den endringen gjøres til den opprinnelige verdien.

3. Parameteroverføring i Java

De grunnleggende begrepene i ethvert programmeringsspråk er "verdier" og "referanser". I Java, Primitive variabler lagrer de faktiske verdiene, mens ikke-primitiver lagrer referansevariablene som peker på adressene til objektene de henviser til. Både verdier og referanser er lagret i stackminnet.

Argumenter i Java overføres alltid etter verdi. Under metodeinnkallelse opprettes en kopi av hvert argument, enten det er en verdi eller referanse, i stackminnet som deretter sendes til metoden.

I tilfelle av primitiver kopieres verdien ganske enkelt inn i stackminnet som deretter sendes til callee-metoden; i tilfelle ikke-primitiver, peker en referanse i stackminne til de faktiske dataene som ligger i dyngen. Når vi passerer et objekt kopieres referansen i stackminnet og den nye referansen sendes til metoden.

La oss nå se dette i aksjon ved hjelp av noen kodeeksempler.

3.1. Passerer primitive typer

Java Programming Language har åtte primitive datatyper. Primitive variabler lagres direkte i stackminnet. Hver gang en variabel av primitiv datatype sendes som et argument, kopieres de faktiske parametrene til formelle argumenter, og disse formelle argumentene samler sin egen plass i stackminnet.

Levetiden til disse formelle parametrene varer bare så lenge den metoden kjører, og når de returneres, blir disse formelle argumentene fjernet fra bunken og kastes.

La oss prøve å forstå det ved hjelp av et kodeeksempel:

public class PrimitivesUnitTest {@Test public void whenModifyingPrimitives_thenOriginalValuesNotModified () {int x = 1; int y = 2; // Før modifisering hevderEquals (x, 1); assertEquals (y, 2); endre (x, y); // Etter endring assertEquals (x, 1); assertEquals (y, 2); } offentlig statisk tomrom modifisere (int x1, int y1) {x1 = 5; y1 = 10; }} 

La oss prøve å forstå påstandene i programmet ovenfor ved å analysere hvordan disse verdiene er lagret i minnet:

  1. Variablene “x ” og “y ” i hovedmetoden er primitive typer, og deres verdier lagres direkte i stackminnet
  2. Når vi kaller metode endre (), blir en eksakt kopi for hver av disse variablene opprettet og lagret på et annet sted i stabelminnet
  3. Enhver endring av disse kopiene berører bare dem og lar de originale variablene være uendret

3.2. Referanser for bestått objekt

I Java lagres alle objekter dynamisk i Heap space under panseret. Disse objektene er henvist fra referanser kalt referansevariabler.

Et Java-objekt, i motsetning til Primitives, lagres i to trinn. Referansevariablene er lagret i stackminnet, og objektet de refererer til, lagres i et Heap-minne.

Hver gang et objekt sendes som et argument, opprettes en eksakt kopi av referansevariabelen som peker på samme plassering av objektet i heapminne som den opprinnelige referansevariabelen.

Som et resultat av dette, når vi endrer det samme objektet i metoden, gjenspeiles den endringen i det opprinnelige objektet. Imidlertid, hvis vi tildeler et nytt objekt til den passerte referansevariabelen, vil den ikke reflekteres i det opprinnelige objektet.

La oss prøve å forstå dette ved hjelp av et kodeeksempel:

public class NonPrimitivesUnitTest {@Test public void whenModifyingObjects_thenOriginalObjectChanged () {Foo a = new Foo (1); Foo b = ny Foo (1); // Før modifisering hevderEquals (a.num, 1); assertEquals (b.num, 1); endre (a, b); // Etter endring assertEquals (a.num, 2); assertEquals (b.num, 1); } offentlig statisk ugyldig modifisering (Foo a1, Foo b1) {a1.num ++; b1 = ny Foo (1); b1.num ++; }} klasse Foo {public int num; offentlig Foo (int num) {this.num = num; }}

La oss analysere påstandene i programmet ovenfor. Vi har passert gjenstander en og b i endre () metode som har samme verdi 1. I utgangspunktet peker disse objektreferansene på to forskjellige objektsteder i et dyngerom:

Når disse referansene en og b blir bestått i endre () metode, lager den speilkopier av disse referansene a1 og b1 som peker på de samme gamle gjenstandene:

I endre () metode når vi endrer referanse a1, det endrer det opprinnelige objektet. Imidlertid for en referanse b1, vi har tildelt et nytt objekt. Så det peker nå på et nytt objekt i hukommelsesminnet.

Enhver endring gjort til b1 vil ikke gjenspeile noe i det opprinnelige objektet:

4. Konklusjon

I denne artikkelen så vi på hvordan parameteroverføring håndteres i tilfelle primitiver og ikke-primitiver.

Vi lærte at parameteroverføring i Java alltid er Pass-by-Value. Imidlertid endres konteksten avhengig av om vi har med primitiver eller objekter å gjøre:

  1. For primitive typer er parametere forbipasseringsverdi
  2. For objekttyper er objektreferansen forbipasserende verdi

Kodebitene som brukes i denne artikkelen, finner du på GitHub.


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