2012-07-20 9 views
5

Sé que en Java, todo se pasa por valor. Pero para los objetos, es el valor de la referencia al objeto que se pasa. Esto significa que a veces un objeto puede cambiarse a través de un parámetro, por lo que, supongo, la gente dice: Nunca modifique parámetros.Pasa por "Valor de referencia"? Alguna aclaración necesaria

Pero en el siguiente código, ocurre algo diferente. s en changeIt() no cambia cuando vuelvas a main():

public class TestClass { 

    static String str = "Hello World"; 

    public static void changeIt(String s) { 
     s = "Good bye world"; 
    } 

    public static void main(String[] args) { 
     changeIt(str); 
     System.out.println(str); 
    } 
} 

supongo - y me gustaría la confirmación - que cuando usted dice s = "something" es igual o equivalente a decir String s = new String("something"). ¿Es por esto que s no cambia? ¿Se le asigna localmente un objeto completamente nuevo que se descarta una vez que sale de changeIt()?

+1

He visto este tipo de pregunta/respuesta antes y * todavía * siento que necesito una revisión. +1 – BlackVegetable

+0

No cambia porque las cadenas en Java son objetos inmutables. – anio

+1

@anio No, esa no es la razón por la cual este código en particular no cambia la cadena. Sería el mismo comportamiento para cualquier objeto, inmutable o no (ya que está haciendo una tarea, no invocando ningún método en el objeto recibido) – nos

Respuesta

4

que cuando usted dice s = "algo" que es el mismo o equivalente a decir Cadena s = new String ("algo")

Sí, más o menos. (aunque la JVM podría hacer optimizaciones para que el mismo literal de cadena usado varias veces se refiera al mismo objeto String).

¿Es esto por lo que s no cambia? ¿Se le asigna un objeto completamente nuevo localmente que se descarta una vez que salga de changeIt()

Sí. Como dices, todo se pasa por valor en Java, incluso referencias a objetos. Entonces la variable s en changeIt(String s) es un valor diferente de str que usa en main(), es solo una variable local dentro del método changeIt. Establecer esa referencia para referenciar otro objeto no afecta a la persona que llama de changeIt.

Tenga en cuenta que el objeto String s se refiere a sigue siendo la misma cadena que str se refiere a al entrar en el método changeIt() antes de asignar un objeto diferente a s

Hay otra cosa que hay que tener en cuenta, y que es que las cadenas son inmutables. Eso significa que ningún método que invoque en un objeto de cadena cambiará esa cadena. p.ej. llamando al s.toLowerCase() dentro de su método changeIt() tampoco afectará a la persona que llama. Eso es porque String.toLowerCase() no altera el objeto, sino que devuelve un nuevo objeto String.

0

Sí, ahora 'S' apunta a un objeto nuevo cuyo alcance está limitado a ese método. La cadena puede no ser un ejemplo perfecto para comprender el concepto de valor por paso. En lugar de cadena, digamos que pasa una referencia de objeto mutable y realiza cambios para asignar un nuevo objeto dentro del método. No los ves fuera del objeto.

public class MyMain { 

    private static void testMyMethod(MyMain mtest) { 
     mtest=new MyMain(); 
     mtest.x=50; 
     System.out.println("Intest method"+mtest.x); 
    } 
    int x=10; 
    public static void main(String... args) 
    { 
     MyMain mtest = new MyMain(); 
     testMyMethod(mtest); 
     System.out.println("In main method: "+mtest.x); 
    } 
} 

Lea las respuestas siguientes en este SO discussion.

+0

Esto es incorrecto, usted ve cambios realizados en objetos mutables: 'static Point myPoint = new Point (0,0); public static void changeIt (Punto p) { p.setLocation (1,0); } \t public static void main (String [] args) { changeIt (myPoint); System.out.println (myPoint); \t} 'Se imprimirá' java.awt.Point [x = 1, y = 0] ' – NominSim

+0

@NominSim: compruebe mi ejemplo y cuando haya definido el parámetro como final, no será posible asignar un nuevo objeto a esa referencia. – kosa

+0

@NominSim: Y si es posible una segunda respuesta en este enlace. http://stackoverflow.com/questions/40480/is-java-pass-by-reference – kosa

3

Cuando se escribe

s = "Good bye world"; 

va a cambiar el valor de s a ser una referencia a la nueva cadena. No está cambiando el valor de la cadena a la que hace referencia el s.

Cuestiones relacionadas