2012-04-24 18 views
5

Este programa da 6 como salida, pero cuando elimino el comentario de la línea 9, la salida es 5. ¿Por qué? Creo que b.a no debería cambiar, debería seguir siendo 5 en principal.Pasa por valor/referencia, ¿qué?

1 class C1{ 
2  int a=5; 

3  public static void main(String args[]){ 
4   C1 b=new C1(); 
5   m1(b); 
6   System.out.println(b.a); 
7  } 

8  static void m1(C1 c){ 
9   //c=new C1(); 
10   c.a=6; 
11 } 
12 } 
+10

Java es * siempre * pase por valor, pero el valor que está pasando es la variable de referencia, por lo que * parece * pasar por referencia en esta situación (pero no lo es). Editar, como @mprabhat declara en su excelente respuesta (1+). También voté por encima de tu pregunta porque no veo por qué se votó negativamente. ¿Estamos bajoneando porque la gente no nace sabiendo Java? –

+1

Debería pasar por las dos versiones de su código en un depurador y ver la diferencia. –

+1

//s.a http://stackoverflow.com/questions/40480/is-java-pass-by-reference – FailedDev

Respuesta

10

Cuando se pasa objeto en Java se pasan como objeto significado de referencia al que hace referencia b en main método y c como argumento en el método m1, ambos punto al mismo objeto, por lo tanto, cuando se cambia el valor a 6 se refleja en el método main.

Ahora, cuando se trata de hacer c = new C1(); entonces se hizo c para apuntar a un objeto diferente, pero b sigue apuntando al objeto que ha creado en su método de main de ahí el valor actualizado 6 no es visible en el método principal y se obtiene 5.

+3

Aquí hay un artículo bastante bueno que explica lo que dice @mprabhat con imágenes si eso te ayuda. http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html – Windle

+0

@Windle muy buen artículo +1 – mprabhat

+0

Aquí dudo, 'Los objetos se pasan por referencia', esta declaración es completamente incorrecto, en mi humilde opinión en Java, en cambio 'Referencias de Objetos son aprobadas por Value', puedo dar un ejemplo maravilloso para esto, aunque los libros dicen lo contrario :-) +1, aunque para el resto de la parte –

3

Está pasando a su método m1 una copia de una referencia a un Objeto de tipo C1.

Si descomenta la línea, toma esa referencia y la señala a otro lugar (no es que la referencia original siga apuntando al primer objeto), de modo que cuando imprima el valor de b, estará imprimiendo el valor del objeto original, que no cambiaste.

Esta pregunta tiene algunas respuestas muy buenas, y realmente debería echarle un vistazo.

Is Java "pass-by-reference" or "pass-by-value"?

+1

Gracias, todavía pienso un poco en términos de punteros en mi cabeza (eso es básicamente lo que son en esencia), pero la referencia es la terminología correcta. – pcalcao

1

esto es porque c en m1 (C1 c) es una referencia a un objeto, y cuando lo hace C.A = 6 ahora a es igual a 6 en este objeto. Pero si haces c = new c1() dentro de este método, c ahora está haciendo referencia a un objeto completamente nuevo, entonces estás haciendo c.a = 6 en este nuevo objeto. Después de que salga del método, y el otro objeto c todavía tiene el valor 5

1

Su método m1(b); se invoca en main, haciendo que una nueva instancia creada en m1 sustituya la instancia ya creada de C1 en el método principal. Si comenta la creación de instancias en m1, la primera instancia en main entra en vigencia. Esto se debe a que en Java los objetos se pasan por referencia, no por valor.

3

Java es pasaje por valor, en términos sencillos, lo que significa que cuando pasa un argumento, crea una copia de , variable de puntero. Las variables de objeto realmente deberían leerse como punteros en C: esto de alguna manera hace que las cosas sean más fáciles de entender, al menos cuando provienen del mundo C (donde C es solo valor por paso).

Así que cuando se hace c=new C1(), o en general cuando se realiza ninguna asignación a c, usted está haciendo c (que anteriormente señaló en la misma ubicación de memoria que b puntas) punto a otro lugar. Por lo tanto, la siguiente c.a=6 es una asignación a un miembro del objeto apuntado por c, que ya no es el objeto apuntado por b.

1

En Java, excepto los tipos primitivos, todo pasa por referencia, aunque dice pasar la copia de la referencia.

Por lo tanto, en su caso, en el primer caso, tanto los punteros byc apuntan al mismo objeto, por lo que el valor actualizado se refleja en el método principal.

En segunda instancia cuando haces c para apuntar a un nuevo objeto (llamando a new) b sigue apuntando al objeto creado en el método principal, por lo tanto, el valor actualizado no se refleja en el método principal ya que b y c apuntan a dos diferentes objetos