java - ¿Es "nuevo String()" inmutable también?
immutability (15)
La cadena es inmutable independientemente de cómo se instancia
1) La respuesta corta es sí , la new String()
es inmutable.
Debido a que cada operación mutable posible (como replace
, toLowerCase
etcetra) que lleva a cabo en String
no afecta la instancia original de String
y le devuelve una nueva instancia .
Puede verificar esto en Javadoc para String
. Cada método public
de String
que está expuesto devuelve una nueva instancia de String
y no altera la instancia actual en la que llamó al método.
Esto es muy útil en el entorno de subprocesos múltiples ya que no tienes que pensar en la mutabilidad ( alguien cambiará el valor ) cada vez que pasas o compartes el String
. String
puede ser fácilmente el tipo de datos más utilizado, por lo que los diseñadores nos han bendecido a todos para no pensar en la mutabilidad cada vez y nos han ahorrado mucho dolor.
Inmutabilidad permitida String pool o caching
Es debido a la propiedad de inmutabilidad que el conjunto interno de cadenas era posible, ya que cuando se requiere el mismo valor de Cadena en otro lugar, se devuelve esa referencia inmutable. Si String
hubiera sido mutable, no habría sido posible compartir String
como esta para ahorrar memoria.
La inmutablidad de la cadena no se debió a la puesta en común, sino que la inmutabilidad tiene más beneficios asociados.
Interno de cadenas o agrupación es un ejemplo de patrón de diseño Flyweight
2) Sí, será internado como cualquier otra String
como una String
blanco también es una String
igual que otras String
.
Referencias
Estuve estudiando Java String por un tiempo. Las siguientes preguntas se basan en las publicaciones siguientes
Java String es especial
Inmutabilidad de String en Java
Inmutabilidad: ahora, pasando por la inmutabilidad, la clase String se ha diseñado de modo que los valores en el conjunto común se puedan reutilizar en otros lugares / variables. Esto es válido si la
String
fue creada comoString a = "Hello World!";
Sin embargo, si creo una cadena comoString b = new String("Hello World!");
¿Por qué es esto inmutable también? (¿O es eso?). Como esto tiene una memoria de pila dedicada, debería poder modificar esto sin afectar a ninguna otra variable. Entonces, por diseño, ¿había alguna otra razón porString
cualString
como un todo se considera inmutable? ¿O está mi suposición anterior incorrecta?Lo segundo que quería preguntar era sobre el grupo común de cadenas . Si creo un objeto de cadena como
String c = "";
es una entrada vacía creada en el grupo?
¿Hay alguna publicación ya en estos? Si es así, ¿alguien podría compartir el enlace?
1) Inmutabilidad: la cadena será inmutable si la creas usando una forma nueva u otra por razones de seguridad
2) Sí, habrá una entrada vacía en el grupo de cadenas.
Puedes entender mejor el concepto usando el código
String s1 = new String("Test");
String s2 = new String("Test");
String s3 = "Test";
String s4 = "Test";
System.out.println(s1==s2);//false
System.out.println(s1==s3);//false
System.out.println(s2==s3);//false
System.out.println(s4==s3);//true
Espero que esto ayude a tu consulta. Siempre puede verificar el código fuente de la clase String en caso de una mejor comprensión Enlace: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java
1) La parte inmutable no se debe a la agrupación; simplemente hace que la piscina sea posible en primer lugar. Las cadenas a menudo se pasan como argumentos a otras funciones o incluso se comparten con otros hilos; Hacer cadenas inmutables fue una decisión de diseño para facilitar el razonamiento en tales situaciones. Entonces, sí , las String
en Java son siempre inmutables, sin importar cómo las crees (ten en cuenta que es posible tener cadenas mutables en Java, pero no con la clase String
).
2) Sí. Probablemente. Realmente no estoy 100% seguro, pero ese debería ser el caso.
1- La cadena es inmutable. Vea esto:
¿Es una cadena de Java realmente inmutable?
Entonces puedes crearlo de muchas maneras.
2-Respuesta corta: Sí estará vacío.
De la documentación de Oracle de Java :
Las cadenas son constantes; sus valores no se pueden cambiar después de que se crean .
Y otra vez:
Los búferes de cadena admiten cadenas mutables. Debido a que los objetos String son inmutables, se pueden compartir.
En términos generales: el objeto "primitivo" (o relacionado) es inmutable (por favor, acepte mi falta de formalismo).
Publicación relacionada sobre desbordamiento de pila:
- Inmutabilidad de cadenas en Java
- Es Java String inmutable?
- ¿Java es "pass-by-reference" o "pass-by-value"?
- ¿Es una cadena de Java realmente inmutable?
- La cadena es inmutable. ¿Cuál es exactamente el significado?
- ¿Cuál es la razón detrás de hacer cadenas inmutables en Java?
Acerca del grupo de objetos : el grupo de objetos es una optimización de Java que NO está relacionada con lo inmutable también.
Esto no es estrictamente una respuesta a su pregunta, pero si detrás de su pregunta está el deseo de tener cadenas mutables que pueda manipular, debería verificar la clase StringBuilder
, que implementa muchos de los mismos métodos que String
pero también agrega métodos para cambiar los contenidos actuales.
Una vez que haya creado su cadena de tal manera que esté satisfecho con ella, simplemente llame a toString()
para convertirla en una String
ordinaria que puede pasar a las rutinas de la biblioteca y otras funciones que solo toman String
s.
Además, tanto StringBuilder
como String
implementan la interfaz CharSequence
, por lo que si desea escribir funciones en su propio código que puedan usar cadenas mutables e inmutables, puede declararlas para tomar cualquier objeto CharSequence
.
La cadena es inmutable porque no le proporciona un medio para modificarla. Está diseñado para evitar cualquier alteración (es definitivo, no se supone que la matriz subyacente debe tocarse ...).
De manera idéntica, Integer es inmutable, porque no hay forma de modificarlo.
No importa cómo lo crees.
La cadena es inmutable significa que no puede cambiar el objeto en sí, sin importar cómo lo haya creado. Y en cuanto a la segunda pregunta: sí, creará una entrada.
La inmutabilidad no es una característica new
, es una característica de la clase String
. No tiene métodos de mutación, por lo que es inmutable.
Las bibliotecas de Java están muy optimizadas en torno a la restricción de que cualquier objeto String
es inmutable, independientemente de cómo se construya ese objeto. Incluso si crea su b
usando un código new
, otro que pase esa instancia tratará el valor como inmutable. Este es un ejemplo del patrón Value Object, y se aplican todas las ventajas (seguridad de subprocesos, sin necesidad de hacer copias privadas).
La cadena vacía ""
es un objeto String
legítimo como cualquier otra cosa, simplemente no tiene contenido interno, y dado que todas las cadenas constantes en tiempo de compilación están intercaladas, prácticamente garantizaré que alguna biblioteca en tiempo de ejecución ya ha causado que sea agregado a la piscina.
Las cadenas creadas siempre serán inmutables independientemente de cómo se creen.
Respuestas a tus preguntas:
La única diferencia es:
Cuando se crea un string como -{String a = "Hello World!";}
, Solo se crea un objeto .
Y cuando se crea como -{String b = new String("Hello World!");}
, Se crean dos objetos . El primero, porque ha usado la palabra clave ''nueva'' y la segunda debido a la propiedad de cadena .Si por su puesto. Habrá una entrada vacía creada en el grupo.
Tenga en cuenta que en su ejemplo, la referencia se cambia y no el objeto al que hace referencia, es decir, b
como referencia puede cambiarse y referirse a un nuevo objeto. Pero ese nuevo objeto es inmutable, lo que significa que su contenido no se cambiará "después" de llamar al constructor.
Puedes cambiar una cadena usando b=b+"x";
o b=new String(b);
, y el contenido de la variable a
parece cambiar, pero no confunde la inmutabilidad de una referencia (aquí la variable b
) y el objeto al que se refiere (piense en punteros en C). El objeto al que apunta la referencia permanecerá sin cambios después de su creación.
Si necesita cambiar una cadena cambiando el contenido del objeto (en lugar de cambiar la referencia), puede usar StringBuffer
, que es una versión mutable de String.
new String()
es una expresión que produce un String
... y un String
es inmutable, sin importar cómo se produce.
(Preguntar si el new String()
es mutable o no, no tiene sentido. Es un código de programa, no un valor. Pero entiendo que eso no es lo que realmente quiso decir).
Si creo un objeto de cadena como
String c = "";
es una entrada vacía creada en el grupo?
Sí; es decir, se crea una entrada para la cadena vacía. No hay nada especial sobre una String
vacía.
(Para ser pedantes, la entrada de pool para ""
se crea mucho antes de que se ejecute su código. De hecho, se crea cuando se carga su código ... o posiblemente incluso antes de eso).
Entonces, quería saber si el nuevo objeto Heap también es inmutable ...
Sí lo es. Pero la inmutabilidad es una propiedad fundamental de los objetos String. Todos los objetos String
.
Verá, la API String
simplemente no proporciona ningún método para cambiar una String
. Entonces (aparte de algunos trucos 1 peligrosos y tontos usando la reflexión), no puedes mutar una String
.
y de ser así, ¿cuál era el propósito ?.
La razón por la que Java String
está diseñado como una clase inmutable es la simplicidad. Hace que sea más fácil escribir programas correctos y leer / razonar sobre el código de otras personas si la clase de cadena principal proporciona una interfaz inmutable. (O al menos, esa es la razón de esta decisión de diseño, tal como yo lo entiendo).
Siguiendo la respuesta, entiendo que otras referencias a la misma variable es una de las razones. Por favor, avíseme si estoy en lo cierto al entender esto.
No. Es más fundamental que eso. Simplemente, todos los objetos String
son inmutables. No es necesario razonar un caso especial complicado para entender esto. Simplemente >> es <<.
Para el registro, si desea un objeto "string-like" mutable en Java, puede usar StringBuilder
o StringBuffer
. Pero estos son tipos diferentes a String.
1 - La razón por la cual estos trucos son (IMO) peligrosos y tontos es que afectan los valores de cadenas potencialmente compartidas por otras partes de su aplicación a través del grupo de cadenas. Esto puede causar caos ... de forma que el siguiente tipo que mantiene tu código tiene pocas posibilidades de localizarlo.
Es al revés, en realidad.
[...] la clase
String
ha sido diseñada para que los valores en el grupo común puedan reutilizarse en otros lugares / variables.
No, la clase String
es inmutable, por lo que puede hacer referencia de forma segura a una instancia de la misma, sin preocuparse de que se modifique desde otra parte de su programa. Esta es la razón por la cual la agrupación es posible en primer lugar.
Por lo tanto, considere esto:
// this string literal is interned and referenced by ''a''
String a = "Hello World!";
// creates a new instance by copying characters from ''a''
String b = new String(a);
Ahora, ¿qué ocurre si simplemente creas una referencia a tu variable b
recién creada?
// ''c'' now points to the same instance as ''b''
String c = b;
Imagine que pasa c
(o, más específicamente, el objeto al que hace referencia) a un método en un subproceso diferente y continúa trabajando con la misma instancia en su subproceso principal. Y ahora imagine lo que sucedería si las cadenas fueran mutables.
¿Por qué es este el caso de todos modos?
Si nada más, es porque los objetos inmutables hacen que el multihilo sea mucho más simple y, por lo general, incluso más rápido. Si comparte un objeto mutable (que sería cualquier objeto con estado, con campos o propiedades mutables privadas / públicas) entre diferentes subprocesos, debe tener especial cuidado para garantizar el acceso sincronizado (mutexes, semáforos). Incluso con esto, necesita cuidados especiales para garantizar la atomicidad en todas sus operaciones. Multithreading es difícil.
En cuanto a las implicaciones de rendimiento, tenga en cuenta que copiar con frecuencia toda la cadena en una nueva instancia, para cambiar incluso un solo carácter, es en realidad más rápido que inducir un costoso cambio de contexto debido a las construcciones de sincronización necesarias para garantizar el acceso a subprocesos. Y como ha mencionado, la inmutabilidad también ofrece posibilidades de internamiento, lo que significa que realmente puede ayudar a reducir el uso de memoria.
En general, es una buena idea hacer tantas cosas inmutables como puedas .
String A = "Test"
String B = "Test"
Ahora String B called
"Test" .toUpperCase () which change the same object into
"TEST" , so
A will also be
"TEST" `que no es deseable.