Considere el siguiente ejemplo.
String str = new String();
str = "Hello";
System.out.println(str); //Prints Hello
str = "Help!";
System.out.println(str); //Prints Help!
Ahora, en Java, los objetos String son inmutables. Entonces, ¿cómo str
puede asignarse el valor del objeto "Ayuda!". ¿No contradice esto la inmutabilidad de las cadenas en Java? ¿Alguien puede explicarme el concepto exacto de inmutabilidad?
Editar:
Okay. Ahora lo entiendo, pero solo una pregunta de seguimiento. ¿Qué pasa con el siguiente código:
String str = "Mississippi";
System.out.println(str); // prints Mississippi
str = str.replace("i", "!");
System.out.println(str); // prints M!ss!ss!pp!
¿Significa esto que se crean dos objetos nuevamente ("Mississippi" y "M! Ss! Ss! Pp!") Y los str
puntos de referencia a un objeto diferente después del replace()
método?
java
string
immutability
Light_handle
fuente
fuente
Respuestas:
str
no es un objeto, es una referencia a un objeto."Hello"
y"Help!"
son dosString
objetos distintos . Por lo tanto,str
apunta a una cadena. Puede cambiar lo que apunta , pero no lo que apunta .Tome este código, por ejemplo:
Ahora, no hay nada 1 que podríamos hacer para
s1
que afectaría el valor des2
. Se refieren al mismo objeto, la cadena"Hello"
, pero ese objeto es inmutable y, por lo tanto, no se puede modificar.Si hacemos algo como esto:
Aquí vemos la diferencia entre mutar un objeto y cambiar una referencia.
s2
todavía apunta al mismo objeto que inicialmente configuramoss1
para apuntar. Ajustes1
a"Help!"
sólo cambia la referencia , mientras que elString
objeto al que se refería originalmente a los restos sin cambios.Si las cadenas fueran mutables, podríamos hacer algo como esto:
Editar para responder a la edición de OP:
Si mira el código fuente de String.replace (char, char) (también disponible en src.zip en su directorio de instalación de JDK, un consejo profesional es buscar allí cada vez que se pregunte cómo funciona realmente algo), puede ver que lo que hace es lo siguiente:
oldChar
en la cadena actual, haga una copia de la cadena actual dondeoldChar
se reemplazan todas las ocurrencias denewChar
.oldChar
no está presente en la cadena actual, devuelva la cadena actual.Entonces sí,
"Mississippi".replace('i', '!')
crea un nuevoString
objeto. De nuevo, lo siguiente es válido:Su tarea por ahora es ver qué hace el código anterior si cambia
s1 = s1.replace('i', '!');
as1 = s1.replace('Q', '!');
:)1 En realidad, es posible mutar cadenas (y otros objetos inmutables). Requiere reflexión y es muy, muy peligroso y nunca debe usarse a menos que esté realmente interesado en destruir el programa.
fuente
El objeto al que hace
str
referencia puede cambiar, pero losString
objetos en sí mismos no pueden.Los
String
objetos que contienen la cadena"Hello"
y"Help!"
no pueden cambiar sus valores, por lo tanto, son inmutables.La inmutabilidad de los
String
objetos no significa que las referencias que apuntan al objeto no puedan cambiar.Una forma de evitar que
str
cambie la referencia es declararla comofinal
:Ahora, intentar asignar otro
String
aSTR
provocará un error de compilación.fuente
str
no es el "objeto", es una referencia al objeto. Si lo haString str = "Hello";
seguidoString anotherReference = str;
, no tiene 2 objetos de cadena, tiene un objeto (el literal "Hola") y 2 referencias a él (str
yanotherReference
).Light_handle Le recomiendo que lea el tamaño de la copa, una historia sobre variables y valor de paso por favor (tamaño de la copa, continuación) . Esto ayudará mucho al leer las publicaciones anteriores.
¿Los has leído? Si. Bueno.
Esto crea un nuevo "control remoto" llamado "
str
" y lo establece en el valornew String()
(o""
).Por ejemplo, en la memoria esto crea:
Esto cambia el control remoto "
str
" pero no modifica la cadena original""
.Por ejemplo, en la memoria esto crea:
Esto cambia el control remoto "
str
" pero no modifica la cadena original""
ni el objeto al que apunta actualmente el control remoto.Por ejemplo, en la memoria esto crea:
fuente
Vamos a dividirlo en algunas partes
Esta instrucción crea una cadena que contiene hola y ocupa espacio en la memoria, es decir, en Constant String Pool y lo asigna al objeto de referencia s1
Esta declaración asigna la misma cadena de saludo a la nueva referencia s2
Ambas referencias apuntan a la misma cadena, por lo que genera el mismo valor de la siguiente manera.
Aunque String es inmutable , la asignación puede ser posible, por lo que s1 ahora se referirá a una nueva pila de valores .
Pero, ¿qué pasa con el objeto s2 que apunta a hola? Será como es.
Como String es inmutable, Java Virtual Machine no nos permitirá modificar la cadena s1 por su método. Creará todos los nuevos objetos String en el grupo de la siguiente manera.
Tenga en cuenta que si String sería mutable, la salida habría sido
Ahora te sorprenderá por qué String tiene métodos como concat () para modificar. El siguiente fragmento borrará tu confusión.
Aquí estamos asignando el valor modificado de la cadena de nuevo a la referencia s1 .
Es por eso que Java decidió que String sea una clase final. De lo contrario, cualquiera puede modificar y cambiar el valor de string. Espero que esto ayude un poco.
fuente
El objeto de cadena al que primero se hizo referencia
str
no se modificó, todo lo que hizo fue hacerstr
referencia a un nuevo objeto de cadena.fuente
La cadena no cambiará, la referencia a ella sí. Estás confundiendo la inmutabilidad con el concepto de
final
campos. Si un campo se declara comofinal
, una vez que se ha asignado, no se puede reasignar.fuente
Con respecto a la parte de reemplazo de su pregunta, intente esto:
fuente
Aunque Java intenta ignorarlo,
str
no es más que un puntero. Esto significa que cuando escribe por primera vezstr = "Hello";
, crea un objeto questr
apunta. Cuando reasignasstr
por escritostr = "Help!";
, se crea un nuevo objeto y el"Hello"
objeto viejo se recolecta cuando cada vez que Java lo desee.fuente
La inmutabilidad implica que el valor de un objeto instanciado no puede cambiar, nunca puede convertir "Hola" en "¡Ayuda!".
La variable str es una referencia a un objeto, cuando asigna un nuevo valor a str no está cambiando el valor del objeto al que hace referencia, está haciendo referencia a un objeto diferente.
fuente
La clase de cadena es inmutable y no puede cambiar el valor del objeto inmutable. Pero en el caso de String, si cambia el valor de string, creará una nueva cadena en el grupo de cadenas y su referencia de cadena a ese valor no al anterior. por lo tanto, la cadena es inmutable. Tomemos tu ejemplo,
creará una cadena "Mississippi" y la agregará al conjunto de cadenas, por lo que ahora str apunta a Mississippi.
Pero después de la operación anterior, se creará una cadena "M! Ss! Ss! Pp!" y se agregará al conjunto de cadenas. y ahora str apunta a M! ss! ss! pp !, no a Mississippi.
así, cuando altere el valor del objeto de cadena, creará un objeto más y lo agregará al grupo de cadenas.
Vamos a tener un ejemplo más.
esta línea de arriba agregará tres objetos de cadena al conjunto de cadenas.
1) Hola
2) Mundo
3) Hola Mundo
fuente
Utilizar:
Si ve aquí, uso el
concat
método para cambiar la cadena original, es decir, "Nueva cadena" con una cadena "Cadena agregada", pero aún así obtuve la salida como anterior, por lo tanto, demuestra que no puede cambiar la referencia del objeto de la clase String, pero si hace esto mediante la clase StringBuilder, funcionará. Se enumera a continuación.fuente
Como dijo Linus Tolvards:
Mira esto:
La salida es
Entonces, recuerda dos cosas:
fuente
Para aquellos que se preguntan cómo romper la inmutabilidad de String en Java ...
Código
Salida
fuente
La cadena es inmutable . Lo que significa que solo podemos cambiar la referencia .
fuente
En Java, a los objetos generalmente se accede por referencias. En su fragmento de código, str es una referencia que primero se asigna a "Hola" (un objeto creado automáticamente o obtenido de un grupo constante ) y luego se le asigna otro objeto "¡Ayuda!" a la misma referencia. Un punto a tener en cuenta es que la referencia es la misma y modificada, pero los objetos son diferentes. Una cosa más en tu código accediste a tres objetos,
Llamar a una nueva cadena () crea un nuevo objeto incluso si existe en el grupo de cadenas, por lo que generalmente no debe usarse. Para poner una cadena creada a partir de la nueva cadena () en el grupo de cadenas, puede probar el
intern()
método.Espero que esto ayude.
fuente
La inmutabilidad que puedo decir es que no se puede cambiar la cadena en sí. Supongamos que tiene String x, cuyo valor es "abc". Ahora no puede cambiar la cadena, es decir, no puede cambiar ningún carácter / s en "abc".
Si tiene que cambiar los caracteres en la Cadena, puede usar una matriz de caracteres y mutarla o usar StringBuilder.
Salida:
fuente
O puedes probar:
Esto mostrará cómo cambia el código hash.
fuente
La cadena es inmutable significa que no puede cambiar el objeto en sí, pero puede cambiar la referencia al objeto. Cuando llamaste a = "ty", en realidad estás cambiando la referencia de a a un nuevo objeto creado por la cadena literal "ty". Cambiar un objeto significa usar sus métodos para cambiar uno de sus campos (o los campos son públicos y no finales, para que puedan actualizarse desde el exterior sin acceder a ellos a través de métodos), por ejemplo:
Mientras está en una clase inmutable (declarada como final, para evitar la modificación por herencia) (sus métodos no pueden modificar sus campos, y también los campos son siempre privados y se recomienda que sean finales), por ejemplo String, no puede cambiar la String actual pero puede devolver una nueva cadena, es decir:
fuente
Aquí la inmutabilidad significa que la instancia puede apuntar a otra referencia, pero el contenido original de la cadena no se modificaría en la referencia original. Déjame explicarte con el primer ejemplo dado por ti. El primer str apunta a "Hola", está bien hasta esto. La segunda vez apunta a "¡Ayuda!". Aquí str comenzó a señalar "¡Ayuda!" y la referencia de la cadena "Hola" se pierde y no podemos recuperarla.
De hecho, cuando str intentaría modificar el contenido existente, se generará otra nueva cadena y str comenzará a apuntar a esa referencia. Entonces, vemos que la cadena en la referencia original no se modifica, pero eso es seguro en su referencia y la instancia del objeto comenzó a apuntar a una referencia diferente para conservar la inmutabilidad.
fuente
Súper tarde a la respuesta, pero quería poner un mensaje conciso del autor de la clase String en Java
Se puede deducir de esta documentación que cualquier cosa que cambie la cadena, devuelva un objeto diferente (que podría ser nuevo o interno y antiguo). La pista no tan sutil sobre esto debería provenir de la firma de la función. Piénselo: "¿Por qué hicieron que una función en un objeto devolviera un objeto en lugar de un estado?".
También una fuente más que hace explícito este comportamiento (de la documentación de la función de reemplazo)
Fuente: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replace(char,%20char)
Fuente: JavaDoc de String.
fuente
La cadena Object - los métodos en sí mismos están hechos para ser "inmutables". Esta acción no produce cambios: "letters.replace (" bbb "," aaa ");"
Pero la asignación de datos causa cambios en el contenido de Strings:
// El hashcode de la cadena Object no cambia.
fuente
Si
HELLO
es la cadena de entonces no se puede cambiarHELLO
aHILLO
. Esta propiedad se llama propiedad de inmutabilidad.Puede tener una variable de cadena de puntero múltiple para apuntar HOLA cadena.
Pero si HOLA es char Array, entonces puedes cambiar HOLA a HILLO. P.ej,
Los lenguajes de programación tienen variables de datos inmutables para que puedan usarse como claves en clave, par de valores.
fuente
Lo explicaría con un simple ejemplo
en la matriz de caracteres podemos realizar operaciones como imprimir solo las últimas tres letras usando iterar la matriz; pero en cadena tenemos que hacer un nuevo objeto de cadena y copiar la subcadena requerida y su dirección estará en un nuevo objeto de cadena.
p.ej
entonces s2 tendrá "hel";
fuente
La cadena en Java en Inmutable y Final solo significa que no se puede cambiar ni modificar:
Caso 1:
Caso 2:
fuente
Debido a que String es inmutable, los cambios no ocurrirán si no asigna el valor devuelto de la función a la cadena. Por lo tanto, en su pregunta, asigne el valor de la función de intercambio devuelto a s.
s = swap (s, n1, n2); entonces el valor de la cadena s cambiará.
También estaba obteniendo el valor sin cambios cuando estaba escribiendo el programa para obtener una cadena de permutaciones (aunque no está dando todas las permutaciones, pero esto es, por ejemplo, para responder a su pregunta)
Aquí hay un ejemplo.
pero no estaba obteniendo los valores permutados de la cadena del código anterior, así que asigné el valor devuelto de la función de intercambio a la cadena y obtuve valores cambiados de la cadena. Después de asignar el valor devuelto obtuve los valores permutados de cadena.
fuente
Producirá poner algo como esto
1419358369 1419358369
103056 65078777
El propósito del objeto inmutable es que su valor no debe modificarse una vez asignado. Devolverá un nuevo objeto cada vez que intente alterarlo según la implementación. Nota: Stringbuffer en lugar de string puede usarse para evitar esto.
A su última pregunta :: u tendrá una referencia y 2 cadenas en el grupo de cadenas. Excepto que la referencia apuntará a m! Ss! Ss! Pp!
fuente