valor través referencia por paso pasaje parámetros parametros funciones enviar ejercicios ejemplos datos java pass-by-reference

java - referencia - paso de parámetros a través de la red



Cómo hacer el equivalente de pasar por referencia para primitivas en Java (6)

Hacer una

class PassMeByRef { public int theValue; }

luego pasa una referencia a una instancia de este. Tenga en cuenta que un método que muta el estado a través de sus argumentos es mejor evitarlo, especialmente en código paralelo.

Este código de Java:

public class XYZ { public static void main(){ int toyNumber = 5; XYZ temp = new XYZ(); temp.play(toyNumber); System.out.println("Toy number in main " + toyNumber); } void play(int toyNumber){ System.out.println("Toy number in play " + toyNumber); toyNumber++; System.out.println("Toy number in play after increement " + toyNumber); } }

dará salida a esto:

Toy number in play 5 Toy number in play after increement 6 Toy number in main 5

En C ++ puedo pasar la variable toyNumber como pase por referencia para evitar el sombreado, es decir, crear una copia de la misma variable como se muestra a continuación:

void main(){ int toyNumber = 5; play(toyNumber); cout << "Toy number in main " << toyNumber << endl; } void play(int &toyNumber){ cout << "Toy number in play " << toyNumber << endl; toyNumber++; cout << "Toy number in play after increement " << toyNumber << endl; }

y la salida de C ++ será esta:

Toy number in play 5 Toy number in play after increement 6 Toy number in main 6

Mi pregunta es: ¿Cuál es el código equivalente en Java para obtener el mismo resultado que el código C ++, dado que Java pasa por valor en lugar de pasar por referencia ?


Java no es llamada por referencia , es solo llamada por valor

Pero todas las variables de tipo de objeto son en realidad punteros.

Entonces, si usas un objeto mutable, verás el comportamiento que deseas

public class XYZ { public static void main(String[] arg) { StringBuilder toyNumber = new StringBuilder("5"); play(toyNumber); System.out.println("Toy number in main " + toyNumber); } private static void play(StringBuilder toyNumber) { System.out.println("Toy number in play " + toyNumber); toyNumber.append(" + 1"); System.out.println("Toy number in play after increement " + toyNumber); } }

Salida de este código:

run: Toy number in play 5 Toy number in play after increement 5 + 1 Toy number in main 5 + 1 BUILD SUCCESSFUL (total time: 0 seconds)

Puede ver este comportamiento en bibliotecas estándar también. Por ejemplo, Collections.sort (); Collections.shuffle (); Estos métodos no devuelven una nueva lista, sino que la modifican como objeto de argumento.

List<Integer> mutableList = new ArrayList<Integer>(); mutableList.add(1); mutableList.add(2); mutableList.add(3); mutableList.add(4); mutableList.add(5); System.out.println(mutableList); Collections.shuffle(mutableList); System.out.println(mutableList); Collections.sort(mutableList); System.out.println(mutableList);

Salida de este código:

run: [1, 2, 3, 4, 5] [3, 4, 1, 5, 2] [1, 2, 3, 4, 5] BUILD SUCCESSFUL (total time: 0 seconds)


No puede pasar primitivas por referencia en Java. Todas las variables del tipo de objeto son en realidad punteros, por supuesto, pero los llamamos "referencias", y también siempre se pasan por valor.

En una situación en la que realmente necesita pasar una primitiva por valor, lo que la gente hará a veces es declarar el parámetro como una matriz de tipo primitivo, y luego pasar una matriz de elemento único como argumento. Entonces pasa una referencia int [1], y en el método, puede cambiar el contenido de la matriz.


Para una solución rápida, puede usar AtomicInteger o cualquiera de las variables atómicas que le permitirán cambiar el valor dentro del método utilizando los métodos incorporados. Aquí hay un código de muestra:

import java.util.concurrent.atomic.AtomicInteger; public class PrimitivePassByReferenceSample { /** * @param args */ public static void main(String[] args) { AtomicInteger myNumber = new AtomicInteger(0); System.out.println("MyNumber before method Call:" + myNumber.get()); PrimitivePassByReferenceSample temp = new PrimitivePassByReferenceSample() ; temp.changeMyNumber(myNumber); System.out.println("MyNumber After method Call:" + myNumber.get()); } void changeMyNumber(AtomicInteger myNumber) { myNumber.getAndSet(100); } }

Salida:

MyNumber before method Call:0 MyNumber After method Call:100


Tienes varias opciones. El que tiene más sentido realmente depende de lo que estás tratando de hacer.

Opción 1: haga que toyNumber sea una variable miembro pública en una clase

class MyToy { public int toyNumber; }

luego pasa una referencia a MyToy a tu método.

void play(MyToy toy){ System.out.println("Toy number in play " + toy.toyNumber); toy.toyNumber++; System.out.println("Toy number in play after increement " + toy.toyNumber); }

Opción 2: devolver el valor en lugar de pasar por referencia

int play(int toyNumber){ System.out.println("Toy number in play " + toyNumber); toyNumber++; System.out.println("Toy number in play after increement " + toyNumber); return toyNumber }

Esta elección requeriría un pequeño cambio al callsite en main para que se lea, toyNumber = temp.play(toyNumber); .

Opción 3: convertirlo en una clase o variable estática

Si las dos funciones son métodos en la misma clase o instancia de clase, puede convertir toyNumber en una variable de miembro de clase.

Opción 4: cree una única matriz de elementos de tipo int y pase esa

Esto se considera un truco, pero a veces se emplea para devolver valores de invocaciones de clase en línea.

void play(int [] toyNumber){ System.out.println("Toy number in play " + toyNumber[0]); toyNumber[0]++; System.out.println("Toy number in play after increement " + toyNumber[0]); }


public static void main(String[] args) { int[] toyNumber = new int[] {5}; NewClass temp = new NewClass(); temp.play(toyNumber); System.out.println("Toy number in main " + toyNumber[0]); } void play(int[] toyNumber){ System.out.println("Toy number in play " + toyNumber[0]); toyNumber[0]++; System.out.println("Toy number in play after increement " + toyNumber[0]); }