Worden arrays doorgegeven door waarde of doorgegeven door verwijzing in Java?

Arrays zijn geen primitief typein Java, maar ze zijn ook geen objecten, net als ze zijn gepasseerd op waarde of op referentie? Hangt het af van wat de array bevat, bijvoorbeeld referenties of een primitief type?


Antwoord 1, autoriteit 100%

Uw vraag is gebaseerd op een onjuist uitgangspunt.

Arrays zijn geen primitief type in Java, maar het zijn ook geen objecten … “

In feite zijn alle arrays in Java objecten1. Elk type Java-array heeft java.lang.Objectals supertype en erft de implementatie van alle methoden in de ObjectAPI.

… dus worden ze doorgegeven op basis van waarde of als referentie? Hangt het af van wat de array bevat, bijvoorbeeld verwijzingen of een primitief type?

Korte antwoorden: 1) geef de waarde door en 2) het maakt niet uit.

Langer antwoord:

Zoals alle Java-objecten worden arrays doorgegeven door waarde … maar de waarde is de verwijzing naar de array. Dus als u iets toewijst aan een cel van de array in de aangeroepen methode, wijst u hetzelfde toe aan hetzelfde array-object dat de beller ziet.

Dit is GEEN pass-by-referentie. Echtepass-by-referentie houdt in dat het adres van een variabelewordt doorgegeven. Met echtepass-by-reference kan de aangeroepen methode worden toegewezen aan zijn lokale variabele, en dit zorgt ervoor dat de variabele in de aanroeper wordt bijgewerkt.

Maar niet in Java. In Java kan de aangeroepen methode de inhoud van de array bijwerken en de kopie van de arrayverwijzing bijwerken, maar niet de variabele in de aanroeper die de arrayverwijzing van de aanroeper bevat. Vandaar … wat Java biedt is GEEN pass-by-referentie.

Hier zijn enkele links die het verschil uitleggen tussen pass-by-referentie en pass-by-waarde. Als je mijn uitleg hierboven niet begrijpt, of als je geneigd bent het niet eens te zijn met de terminologie, moetze lezen.

Verwante SO-vraag:

Historische achtergrond:

De zinsnede “pass-by-reference” was oorspronkelijk “call-by-reference” en werd gebruikt om het argument te onderscheiden dat de semantiek van FORTRAN (call-by-reference) doorgeeft van die van ALGOL-60 (call-by-reference). op waarde en op naam).

  • In call-by-value wordt de argumentuitdrukking geëvalueerd tot een waarde en die waarde wordt gekopieerd naar de aangeroepen methode.

  • In call-by-reference wordt de argumentexpressie gedeeltelijk geëvalueerd tot een “lvalue” (d.w.z. het adres van een variabele of array-element) die wordt doorgegeven aan de aanroepende methode. De aanroepmethode kan dan direct de variabele / het element lezen en bijwerken.

  • In call-by-name wordt de daadwerkelijke argumentexpressie doorgegeven aan de roepmethode (!!) die het meerdere keren kan evalueren (!!!). Dit was gecompliceerd om te implementeren, en kon (misbruikt) kunnen worden gebruikt om code te schrijven die erg moeilijk te begrijpen was. Call-by-name werd alleen in Algol-60 gebruikt (Gelukkig!).

update

Eigenlijk is algol-60’s call-by-by-by-name vergelijkbaar met het passeren van Lambda-uitdrukkingen als parameters. Het rimpel is dat deze niet-exact-lambda-expressies (ze werden “Thunks” op het implementatieniveau) aangeduid aan het indirect wijzigen de status van variabelen die in de roepingsprocedure / functie zijn . Dat maakt deel uit van wat hen zo moeilijk heeft gemaakt te begrijpen. (Zie de Wikipedia-pagina op Jensen’s apparaat bijvoorbeeld.)


1. Niets in de gekoppelde Q & AMP; A (arrays in Java en Hoe ze worden opgeslagen in het geheugen ) of inhoudt of impliceert dat arrays geen objecten zijn.


2, Autoriteit 179%

Alles in Java wordt gepasseerd door waarde. In het geval van een array (die niets anders is dan een object), wordt de array-referentie gepasseerd door waarde (net als een objectreferentie wordt gepasseerd door de waarde) .

Wanneer u een array naar een andere methode passeert, wordt eigenlijk de verwijzing naar die array gekopieerd.

  • Elke wijzigingen in de content van de array door die verwijzing beïnvloedt de oorspronkelijke array.
  • Maar het wijzigen van de verwijzing naar het punt naar een nieuwe array zal de bestaande referentie in de oorspronkelijke methode niet wijzigen.

Zie dit bericht: is Java “pass-by-reference” of “pass-by- waarde “?

Zie dit werkvoorbeeld:

public static void changeContent(int[] arr) {
   // If we change the content of arr.
   arr[0] = 10;  // Will change the content of array in main()
}
public static void changeRef(int[] arr) {
   // If we change the reference
   arr = new int[2];  // Will not change the array in main()
   arr[0] = 15;
}
public static void main(String[] args) {
    int [] arr = new int[2];
    arr[0] = 4;
    arr[1] = 5;
    changeContent(arr);
    System.out.println(arr[0]);  // Will print 10.. 
    changeRef(arr);
    System.out.println(arr[0]);  // Will still print 10.. 
                                 // Change the reference doesn't reflect change here..
}

3, Autoriteit 40%

Arrays zijn in feite objecten, dus een referentie wordt gepasseerd (de referentie zelf wordt doorgegeven door waarde, in de war?). Snel voorbeeld:

// assuming you allocated the list
public void addItem(Integer[] list, int item) {
    list[1] = item;
}

U ziet de wijzigingen in de lijst van de roepcode. U kunt echter niet de referentie zelf wijzigen, omdat het wordt aangenomen door waarde:

// assuming you allocated the list
public void changeArray(Integer[] list) {
    list = null;
}

Als u een niet-nullijst passeert, wordt deze niet null op de tijd dat de methode retourneert.


4, Autoriteit 8%

Nee dat is verkeerd. Arrays zijn speciale objecten in Java. Dus het is als het passeren van andere objecten waar u de waarde van de referentie doorgeeft, maar niet de referentie zelf. Betekenis, het wijzigen van de referentie van een array in de genoemde routine zal niet worden weerspiegeld in de routine.


Antwoord 5, autoriteit 3%

Alles in Java wordt doorgegeven door waarde .

In het geval van de array wordt de referentie gekopieerd naar een nieuwe referentie, maar onthoud dat alles in Java wordt doorgegeven door waarde .

Bekijk dit interessante artikelvoor meer informatie …


6

Soort een truc Realty … Zelfs referenties worden gepasseerd door waarde in Java, vandaar dat een verandering in de referentie zelf wordt gescheurd op het gebelde functieniveau. De compiler en / of JVM zullen vaak een waardetype in een referentie maken.

Other episodes