metodos llenar listas imprimir enteros ejemplos como clase java parameters call-by-value pass-by-reference

java - llenar - ¿Por qué se modifica un parámetro ArrayList, pero no un parámetro String?



listas en java netbeans (5)

En el caso de los objetos de cadena Arraylist, los elementos agregados se recuperan. En el caso de String, la llamada al método no tiene efecto en la String que se pasa.

Sucede porque Java es Pass-by-Value y las String son inmutables.

Cuando usted llama

markAsNull(ArrayList<String> str)

La nueva referencia por nombre str se crea para la misma ArrayList apuntada por al . Cuando add un elemento en str , se agrega al mismo objeto. Más tarde, coloca str en null pero el objeto tiene los nuevos valores agregados y apunta a1 .

Cuando usted llama

markStringAsNull(String str) { str = str + "Append me"; // ... }

La línea str = str + "Append me"; crea un nuevo objeto String agregando la cadena dada y asignándola a str . pero nuevamente es solo una referencia a la cadena real que ahora apunta a la cadena recién creada. (debido a la inmutabilidad) y la cadena original no se cambia.

Esta pregunta ya tiene una respuesta aquí:

public class StackOverFlow { public static void main(String[] args) { ArrayList<String> al = new ArrayList<String>(); al.add("A"); al.add("B"); markAsNull(al); System.out.println("ArrayList elements are "+al); String str = "Hello"; markStringAsNull(str); System.out.println("str "+ str); } private static void markAsNull(ArrayList<String> str){ str.add("C"); str= null; } private static void markStringAsNull(String str){ str = str + "Append me"; str = null; } }

Esto produce:

ArrayList elements are [A, B, C] str Hello

En el caso de ArrayList , los elementos añadidos se recuperan. En el caso de String la llamada al método no tiene efecto en la String que se pasa. ¿Qué es exactamente lo que está haciendo la JVM? ¿Alguien puede explicar en detalle?


Del libro: SCJP - Programador certificado de Sun para Java 6 Guía de estudio (Katty Sierra - Bert Bates) Capítulo 3 Objetivo 7.3 - Pasar variables a los métodos

Java es en realidad el paso por valor para todas las variables que se ejecutan dentro de una sola máquina virtual. Pasar por valor significa pasar por valor variable. Y eso significa, paso por copia de la variable!

La línea inferior en el paso por valor: el método llamado no puede cambiar la variable de la persona que llama, aunque para las variables de referencia de objeto, el método llamado puede cambiar el objeto al que se refiere la variable. ¿Cuál es la diferencia entre cambiar la variable y cambiar el objeto? Para referencias de objetos, significa que el método llamado no puede reasignar la variable de referencia original de la persona que llama y hacer que se refiera a un objeto diferente, o nulo. Por ejemplo, en el siguiente fragmento de código,

void bar() { Foo f = new Foo(); doStuff(f); } void doStuff(Foo g) { g.setName("Boo"); g = new Foo(); }

reasignar g no reasigna f! Al final del método de la barra (), se crearon dos objetos Foo, uno referenciado por la variable local f y otro referenciado por la variable local (argumento) g. Debido a que el método doStuff () tiene una copia de la variable de referencia, tiene una forma de llegar al objeto Foo original, por ejemplo, para llamar al método setName (). Pero, el método doStuff () no tiene una manera de llegar a la variable de referencia f. Así que doStuff () puede cambiar los valores dentro del objeto f, pero doStuff () no puede cambiar el contenido real (patrón de bits) de f. En otras palabras, doStuff () puede cambiar el estado del objeto al que se refiere f, pero no puede hacer que f se refiera a un objeto diferente.


En Java, puede crear un objeto y hacer referencia a varios punteros. Llamar a un método mutador en cualquier puntero modificará efectivamente el único objeto, actualizando así todas las demás referencias.

Pero si llama a las instrucciones de asignación de variables en una referencia, solo se cambiará ese puntero, ya que no realiza ningún trabajo del lado del objeto (esto es lo mejor que podría explicar ...).

Pasar un objeto a un parámetro efectivamente copiará la referencia, dando como resultado un solo objeto, con dos punteros: uno global y otro local.

Un punto más, ya que String es inmutable, en realidad obtendrá un nuevo objeto, que es distinto del original (del hecho de que tiene que decir a = a + "a" ), por eso no modificará el objeto. cadena original


Java sigue el concepto de valor de paso (no hay paso por referencia en java). Entonces, cuando pasa una cadena a la función, esta envía una "copia de referencia" a esa cadena. Entonces, incluso si establece la variable en nula en la función, cuando regresa a la persona que llama, solo se refiere a su valor original. Es por eso que la cadena original no tiene efecto.

En el caso de Arraylist, la copia de referencia se refiere al Arraylist original (que también es el mismo en el caso de una cadena). Pero cuando agrega algo a ArrayList, se refiere al objeto original y para que pueda ver el efecto. (pruebe con el método arraylist = new ArrayList (), su arraylist original permanecerá como está).

En caso de cadena, cuando lo hagas.

str = str + "abc";

Java crea un nuevo objeto String que tendrá referencia a la cadena "xyzabc" (por ejemplo, str = "xyz") y "xyz" será elegible para la recolección de basura. Pero como "xyz" todavía tiene una variable que se refiere a ella (cadena original) no se recolectará como basura. Pero tan pronto como la llamada a la función supera, "xyzabc" pasa a la recolección de basura.

El resumen de la discusión es que, siempre que una referencia se refiera al mismo objeto, puede realizar cambios en la función, pero cuando intenta cambiar la referencia (str = str + "abc"), se refiere al nuevo objeto en el método. para que tu objeto original se quede como está.


Los métodos markXAsNull establecen que las referencias locales sean null . Esto no tiene efecto en el valor real almacenado en esa ubicación. El método main todavía tiene sus propias referencias a los valores, y puede llamar a println usando esos.

Además, al realizar la concatenación de cadenas, se llama a toString() en el Objeto, y es por eso que ArrayList se muestra como una lista de sus valores entre paréntesis.