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

Resuelto Student asked hace 13 años • 8 respuestas

Este código 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);   
    }   
}  

generará esto:

 
Juguete número 5 en juego.  
Número de juguete en juego después del incremento 6  
Número de juguete en 5 principales.  

En C++ puedo pasar la toyNumbervariable como paso 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:

Juguete número 5 en juego.  
Número de juguete en juego después del incremento 6  
Número de juguete en el 6 principal.  

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 se pasa por valor en lugar de por referencia ?

Student avatar Apr 11 '11 03:04 Student
Aceptado

Tienes varias opciones. El que tenga más sentido realmente depende de lo que estés intentando hacer.

Opción 1: hacer de toyNumber una variable miembro pública en una clase

class MyToy {
  public int toyNumber;
}

luego pase una referencia a MyToy a su 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 en el sitio de llamada en principal para que diga: toyNumber = temp.play(toyNumber);.

Opción 3: conviértalo 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 miembro de clase.

Opción 4: crear una matriz de un solo elemento de tipo int y pasarla

Esto se considera un truco, pero a veces se emplea para devolver valores de invocaciones de clases 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]);   
}
laslowh avatar Apr 10 '2011 20:04 laslowh

Java no se llama por referencia , se llama solo 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)

También puedes ver este comportamiento en las bibliotecas estándar. Por ejemplo Colecciones.sort(); Colecciones.shuffle(); Estos métodos no devuelven una nueva lista sino que modifican su objeto 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)
Kerem Baydoğan avatar Apr 10 '2011 20:04 Kerem Baydoğan