2009-01-28 29 views
11

Tengo una pregunta sobre el cambio de los valores de las variables en los métodos en Java.Cambiando los valores de las variables en los métodos, Java

Este es mi código:

public class Test { 
    public static void funk(int a, int[] b) { 
     b[0] = b[0] * 2; 
     a = b[0] + 5; 
    } 

    public static void main(String[] args) { 
     int bird = 10; 
     int[] tiger = {7}; 

     Test.funk(bird, tiger); 
    } 
} 

Después de la ejecución del método Test.funk(bird, tiger), el valor de las aves no se cambia - se queda con el valor 10, a pesar de que en el método funk() hemos cambiado el valor con a = b[0] + 5;

por otro lado, el valor del elemento en los cambios de la matriz, porque tenemos la declaración b[0] = b[0] * 2;

I no entiendo por qué una cosa cambia y la otra no? ¿Podría alguien explicar esto por mí?

Respuesta

17

Mira el artículo de Jon Skeet sobre Parameter-Passing in Java, que explica esto.

En pocas palabras (se ven en su sitio para una explicación más largo):

Las matrices son los tipos de referencia. Si pasa una referencia que apunta a una matriz, el valor de la referencia se copia y se asigna al parámetro de la función. Entonces, el parámetro apuntará a la misma matriz que el argumento que se pasó. Por lo tanto, los cambios que realice en la matriz a través del parámetro de su función serán visibles en la función de llamada. Sin embargo, la función de llamada no cambiará el parámetro mismo (b), por ejemplo configurándolo en nulo, ya que el parámetro (b) es solo una copia del argumento (tigre) pasado.

Los enteros son los llamados tipos primitivos. Pasar el entero copia su valor y lo asigna al parámetro también. Pero ese valor no es una referencia a los datos reales, sino que es la información en sí misma. Entonces los cambios en el parámetro en la función afectarán el parámetro (a), pero no el argumento pasado en la función de llamada (pájaro).

4

Eso es porque cuando se declara

public static void funk(int a, int[] b) 

El alcance de la variable un es solamente ese método. Luego, cuando cambie el valor, solo está cambiando el valor de que variable en ese método.

Sobre la b. Eso es una nueva referencia de objeto a la misma matriz creada en el principal, es por eso que parece el valor no cambio (lo que está cambiando es el objeto de matriz por debajo)

Pero intente esto:

public static void funk(int a, int[] b) { 
    // create a new reference for b 
    int[] c = new int[b.length]; 
    c[0] = b[0]; 
    b = c; 

    // The same. 
    b[0] = b[0] * 2; 
    a = b[0] + 5; 
} 

Cuando haz que el valor de tigre no cambie tampoco (solo el contenido de la nueva matriz creada en funk)

Puedes simular el pase ref utilizando un contenedor.See this post.

Aunque no tengo ningún comentario sobre eso

EDITAR Sólo por diversión:

he modificado el código para utilizar la envoltura publicado anteriormente.

Parece bastante extraño, pero parece que funciona.

// By ref simulated. 
public class Test { 

    public static void funk(_<Integer> a, int[] b) { 
     b[0] = b[0] * 2; 
     a.s( b[0] + 5) ; 
    } 

    public static void main(String[] args) { 
     _<Integer> bird = new _<Integer>(10); 
     int[] tiger = {7}; 

     Test.funk(bird , tiger); 

     System.out.println("bird = " + bird); 
     System.out.println("tiger = " + tiger[0]); 

    } 

} 

Prints

bird = 19 
tiger = 14 

: -S

4

Básicamente, los objetos (como las matrices) se pasan a los métodos "por referencia". Entonces, cuando cambia el objeto, cambia el mismo objeto que se pasó al método.

primitivas (como int) son "pasa por valor", por lo que la variable que se va a asignar un valor a una no es lo mismo que la variable int que fue aprobada en.

Espero que esto ayude .. .

+1

no, no ayuda. Java SIEMPRE es pass-by-value. Lea los enlaces proporcionados en las otras respuestas; necesitas entender esto –

+0

Para este ejemplo mi explicación 'básica' está bien. Dejé en claro que era una explicación básica. Si el interlocutor quiere leer una explicación más detallada, los enlaces están ahí para él. No tengo forma de decir cuántos detalles requiere, así que pensé que podría apreciar la elección. – stephendl

+1

Sí, lo aprecié. También leo los enlaces, pero las explicaciones más cortas también son útiles para comenzar. Gracias a todos. – user42155

Cuestiones relacionadas