In Java, arguments are passed by value or by reference?

-3

I always thought that in Java the parameters are passed by reference in the case of objects and by value in the case of primitive types. But there are sites where it is said that all parameters are passed by value, for example, here (in English) , which They indicate that this is not true. I think I do not understand the difference they are making. What is the explanation?

This question is a translated and modified copy of the original Is Java" pass-by-reference "or" pass-by-value "? which is a wiki community comunity originally written by user4315 and does not necessarily represent the opinion of user4315 about it.

    
asked by Jose Antonio Dura Olmos 18.12.2015 в 23:12
source

2 answers

7

In Java the arguments are passed always by value. Unfortunately, for programmers who switched from C ++ to Java, this causes confusion because in Java they decided to call references to something that is very different from C ++ references. The reason for this is that references in Java are passed by value . This is what happens:

public class Test {
    public static void main( String[] args ) {
        Perro unPerro = new Perro("Lupo");
        cambiarNombre(unPerro);
        System.out.println( "Ahora el perro se llama : " + 
                            unPerro.obtenerNombre() );
    }

    public static void cambiarNombre(Perro p) {
        p = new Perro("Fifi");
    }
}

In this example, unPerro.obtenerNombre() still returns "Lupo" . The value of the variable unPerro is not overwritten in the method cambiarNombre with the Perro called "Fifi" since the reference to the object is passed by value. This means that in the cambiarNombre method you pass a copy of the value of the object reference Perro found in the client method (for this case, main ). If passed by reference, then unPerro.obtenerNombre() in main would return "Fifi" after calling cambiarNombre since the reference stored in object Perro declared in the client method has been updated.

For the name to be changed, the cambiarNombre method should alter the status of the value of the object sent as a parameter. This is achieved as follows:

public static void cambiarNombre(Perro p) {
    p.asignaNombre("Fifi");
}

That is, from the cambiarNombre method we can change the content of Perro that is passed to you and those changes will then be reflected in the Perro referenced by unPerro . But since cambiarNombre we can not make the variable unPerro referent to another Perro .

The implementation of Perro is:

public class Perro {
    private String miNombre;
    public Perro(String nombre) {
        miNombre = nombre;
    }
    public String obtenerNombre() {
        return miNombre;
    }
    public void asignaNombre(String nombre) {
        miNombre = nombre;
    }
}

A common source of confusion is to think that references in Java and C ++ are similar because they have the same name. This is indisputably false. You have a detailed description of this in this question and answer .

This response is a translated and modified copy of an original answer in English that is a wiki community written by erlando . And it does not necessarily reflect the opinion of erlando.

    
answered by 18.12.2015 / 23:12
source
1

In Java the parameters are passed by value, although there are cases in which the code is executed in a similar way to that if it were step by reference, but this is not the case.

When you send a Java parameter, it creates a copy of the variable and sends it to the method. If you use primitive data you should not give it more importance, simply the content of the variable will be equal to the value before being sent to the method.

If the parameters you send are objects, you should be aware that they are mutable or immutable. If you are mutable you must be very careful, since a copy of that reference is created pointing to the same object. Therefore, the change you make within a method will affect the original variable.

I leave an example for you to validate for yourself:

public static void main(String[] args)
{
    int variableA = 5;
    int variableB = 10;

    System.out.println("variable A antes del intercambio : " +variableA);
    System.out.println("variable B antes del intercambio : " +variableB);

    intercambio(variableA, variableB);

    System.out.println("variable A despues del intercambio : " +variableA);
    System.out.println("variable B despues del intercambio : " +variableB);


    StringBuilder cadenaA = new StringBuilder("cadenaA");
    StringBuilder cadenaB = new StringBuilder("cadenaB");

    System.out.println("cadena A antes del intercambio : " +cadenaA);
    System.out.println("cadena B antes del intercambio : " +cadenaB);

    intercambio(cadenaA, cadenaB);

    System.out.println("cadena A despues del intercambio : " +cadenaA);
    System.out.println("cadena B despues del intercambio : " +cadenaB);


}

public static void intercambio(int variableA,int variableB)
{
    System.out.println("variable A dentro del metodo : " +variableA);
    System.out.println("variable B dentro del metodo : " +variableB);

    int auxiliar = variableA;
    variableA = variableB;
    variableB = auxiliar;

    System.out.println("variable A dentro del metodo : " +variableA);
    System.out.println("variable B dentro del metodo : " +variableB);
}

public static void intercambio(StringBuilder cadenaA,StringBuilder cadenaB)
{
    System.out.println("cadena A dentro del metodo : " + cadenaA);
    System.out.println("cadena B dentro del metodo : " + cadenaB);

    cadenaA.append("texto");
    cadenaB.append("texto");

    System.out.println("cadena A dentro del metodo : " + cadenaA);
    System.out.println("cadena B dentro del metodo : " + cadenaB);

}
    
answered by 12.05.2017 в 05:18