Me preguntaron en una entrevista por qué String es inmutable
Respondí así:
Cuando creamos una cadena en Java como
String s1="hello";
entonces, se creará un objeto en el conjunto de cadenas (hola) y s1 apuntará a hola . Ahora, si lo hacemos nuevamente, noString s2="hello";
se creará otro objeto, pero s2 señalaráhello
porque JVM primero comprobará si el mismo objeto está presente en el conjunto de cadenas o no. Si no está presente, solo se crea uno nuevo o no.
Ahora, si supongamos que java permite una cadena mutable, entonces si cambiamos s1 a hello world
entonces el valor s2 también será hello world
así que java String es inmutable.
¿Puede alguien decirme si mi respuesta es correcta? o incorrecta ?
std::string
es mutable, pero también tienen un grupo de cadenas (bueno, más correctamente, grupo de matriz de caracteres).Respuestas:
String
es inmutable por varias razones, aquí hay un resumen:String
en conexiones de red, URL de conexión de base de datos, nombres de usuario / contraseñas, etc. Si fuera mutable, estos parámetros podrían cambiarse fácilmente.String
se utiliza como argumentos para la carga de clases. Si es mutable, podría provocar que se cargue una clase incorrecta (porque los objetos mutables cambian su estado).Dicho esto, la inmutabilidad de
String
solo significa que no puede cambiarlo utilizando su API pública. De hecho, puede omitir la API normal utilizando la reflexión. Mira la respuesta aquí .En su ejemplo, si
String
era mutable, considere el siguiente ejemplo:fuente
String
es mutable, el cargador de clases tomaría la cadena que se pasaba, haría una copia y no cambiaría su copia. Cuando piense en un problema conjava.lang.String
s mutable , piense en cómo C ++ resuelve este problema (ya que tienestd::string
s mutable .Los desarrolladores de Java deciden que las cadenas son inmutables debido al siguiente diseño de aspecto , eficiencia y seguridad .
Las cadenas de diseño se crean en un área de memoria especial en el montón de Java conocida como "grupo interno de cadenas". Mientras crea una nueva cadena (no en el caso de usar el constructor String () o cualquier otra función String que internamente use el constructor String () para crear un nuevo objeto String; el constructor String () siempre crea una nueva cadena constante en el grupo a menos que llame al método interno () ) variable que busca en el grupo para verificar si ya existe. Si existe, devuelva la referencia del objeto String existente. Si la cadena no es inmutable, cambiar la cadena con una referencia conducirá al valor incorrecto para las otras referencias.
De acuerdo con este artículo en DZone:
fuente
No podemos estar seguros de qué pensaban realmente los diseñadores de Java mientras diseñaban,
String
pero solo podemos concluir estas razones en función de las ventajas que obtenemos de la inmutabilidad de cadenas, algunas de las cuales son1. Existencia del conjunto constante de cadenas
Como se discutió en Por qué String se almacena en String Constant Pool , cada aplicación crea demasiados objetos de cadena y para evitar que JVM cree primero muchos objetos de cadena y luego los recolecte basura. JVM almacena todos los objetos de cadena en un área de memoria separada llamada Grupo constante de cadenas y reutiliza los objetos de ese grupo en caché.
Siempre que creamos un literal de cadena, JVM ve primero si ese literal ya está presente en un grupo constante o no, y si está allí, la nueva referencia comenzará a apuntar al mismo objeto en SCP.
En el ejemplo anterior, con objeto de cadena de valor
Naresh
será creado en el SCP sólo una vez y toda referenciaa
,b
,c
apuntará al mismo objeto, pero lo que si tratamos de hacer un cambio ena
por ejemploa.replace("a", "")
.Idealmente,
a
debería tener valor ,Nresh
pero debería permanecer sin cambios porque, como usuario final, solo estamos haciendo el cambio . Y sabemos , , todos apuntan al mismo objeto por lo que si hacemos un cambio enb
c
a
a
b
c
a
, otros también debe reflejar el cambio.Pero la inmutabilidad de cadena nos salva de este escenario y, debido a la inmutabilidad del objeto de cadena, el objeto de cadena
Naresh
nunca cambiará. Entonces, cuando hacemos algún cambio ena
lugar de un cambio en el objeto de cadena,Naresh
JVM crea un nuevo objeto al que se lo asignaa
y luego realiza un cambio en ese objeto.Entonces, el conjunto de cadenas solo es posible debido a la inmutabilidad de String y si String no hubiera sido inmutable, entonces el almacenamiento en caché de los objetos de cadena y su reutilización no tendrían la posibilidad de que ninguna variable hubiera cambiado el valor y corrompido a otros.
Y es por eso que JVM lo maneja de manera muy especial y se le ha dado un área de memoria especial.
2. Seguridad del hilo
Un objeto se llama seguro para subprocesos cuando varios subprocesos están operando en él, pero ninguno de ellos puede corromper su estado y el objeto mantiene el mismo estado para cada subproceso en cualquier momento.
Como nosotros, un objeto inmutable no puede ser modificado por nadie después de su creación, lo que hace que cada objeto inmutable sea seguro para subprocesos de forma predeterminada. No necesitamos aplicarle ninguna medida de seguridad de subprocesos, como crear métodos sincronizados.
Entonces, debido a su naturaleza inmutable, el objeto de cadena puede ser compartido por múltiples hilos e incluso si está siendo manipulado por muchos hilos, no cambiará su valor.
3. Seguridad
En cada aplicación, necesitamos pasar varios secretos, por ejemplo, nombre de usuario \ contraseñas del usuario, URL de conexión y, en general, toda esta información se pasa como el objeto de cadena.
Ahora suponga que si String no hubiera sido inmutable por naturaleza, causaría una seria amenaza a la seguridad de la aplicación porque estos valores pueden modificarse y si se permite, estos podrían modificarse debido a un código escrito incorrectamente o cualquier otra persona que tener acceso a nuestras referencias variables.
4. Carga de clase
Como se discutió en Crear objetos a través de Reflection en Java con Example , podemos usar
Class.forName("class_name")
método para cargar una clase en la memoria que nuevamente llama a otros métodos para hacerlo. E incluso JVM usa estos métodos para cargar clases.Pero si ve claramente que todos estos métodos aceptan el nombre de la clase como un objeto de cadena, por lo que las cadenas se usan en la carga de clases de Java y la inmutabilidad proporciona seguridad por la que se carga la clase correcta
ClassLoader
.Supongamos que String no hubiera sido inmutable y estamos tratando de cargar los
java.lang.Object
que se han cambiadoorg.theft.OurObject
en el medio y ahora todos nuestros objetos tienen un comportamiento que alguien puede usar para cosas no deseadas.5. Almacenamiento en caché de HashCode
Si vamos a realizar operaciones relacionadas con el hash en cualquier objeto, debemos anular el
hashCode()
método e intentar generar un código hash preciso utilizando el estado del objeto. Si se cambia el estado de un objeto, lo que significa que su código hash también debería cambiar.Debido a que String es inmutable, el valor que tiene un objeto de cadena nunca cambiará, lo que significa que su código hash tampoco cambiará, lo que le da a la clase String la oportunidad de almacenar en caché su código hash durante la creación del objeto.
Sí, el objeto String almacena en caché su código hash en el momento de la creación del objeto, lo que lo convierte en el gran candidato para operaciones relacionadas con el hash porque el código hash no necesita calcularse nuevamente, lo que nos ahorra algo de tiempo. Es por eso que String se usa principalmente como
HashMap
teclas.Lea más sobre por qué String es inmutable y final en Java .
fuente
La razón más importante según este artículo en DZone:
Espero que te ayude.
fuente
Leí esta publicación Por qué String es inmutable o final en Java y supongo que lo siguiente puede ser la razón más importante:
fuente
Tienes razón.
String
en java usa el concepto deString Pool
literal. Cuando se crea una cadena y si la cadena ya existe en el grupo, se devolverá la referencia de la cadena existente, en lugar de crear un nuevo objeto y devolver su referencia. Si una cadena no es inmutable, cambiar la cadena con una referencia conducir al valor incorrecto para las otras referencias.Agregaría una cosa más, ya que
String
es inmutable, es seguro para subprocesos múltiples y una sola instancia de String se puede compartir entre diferentes subprocesos. Esto evita el uso de la sincronización para la seguridad del subproceso, las cadenas están implícitamentethread safe
.fuente
La clase de cadena
FINAL
significa que no puede crear ninguna clase para heredarla y cambiar la estructura básica y hacer que Sting sea mutable.Otra cosa, la variable de instancia y los métodos de la clase String que se proporcionan son tales que no puede cambiar el
String
objeto una vez creado.La razón por la que ha agregado no hace que la cadena sea inmutable en absoluto. Todo esto dice cómo se almacena la cadena en el montón. También el conjunto de cadenas hace la gran diferencia en el rendimiento
fuente
La cadena se da como inmutable por los micro sistemas de Sun, porque la cadena se puede usar para almacenar como clave en la colección de mapas. StringBuffer es mutable. Esa es la razón, no se puede usar como clave en el objeto de mapa
fuente
La razón más importante de que una cadena se haga inmutable en Java es la consideración de seguridad . El siguiente sería el almacenamiento en caché .
Creo que otras razones dadas aquí, como la eficiencia, la concurrencia, el diseño y el conjunto de cadenas se derivan del hecho de que String in inmutable. Por ej. String Pool podría crearse porque String era inmutable y no al revés.
Verifique la transcripción de la entrevista de Gosling aquí
fuente
Además de las excelentes respuestas, quería agregar algunos puntos. Al igual que Strings, Array contiene una referencia al inicio de la matriz, por lo que si crea dos matrices
arr1
earr2
hizo algo asíarr2 = arr1
, la referencia será laarr2
misma,arr1
por lo que cambiar el valor en una de ellas dará como resultado el cambio de la otra, por ejemploNo solo eso causaría errores en el código, sino que también puede (y será) explotado por un usuario malintencionado. Supongamos que tiene un sistema que cambia la contraseña de administrador. El usuario tiene que ingresar primero el
newPassword
y luego eloldPassword
si eloldPassword
mismo queadminPass
el programa cambia la contraseñaadminPass = newPassword
. supongamos que la nueva contraseña tiene la misma referencia que la contraseña de administrador, por lo que un mal programador puede crear unatemp
variable para mantener la contraseña de administrador antes de que los usuarios ingresen datos sioldPassword
es igual atemp
si cambia la contraseña.adminPass = temp
. Alguien que sepa que podría ingresar fácilmente la nueva contraseña y nunca ingresar la contraseña anterior y abracadabra tiene acceso de administrador. Otra cosa que no entendí cuando aprendí sobre Strings es por qué JVM no crea una nueva cadena para cada objeto y tiene un lugar único en la memoria para ello y puede hacerlo usandonew String("str");
la razón por la que no querría usar siemprenew
es porque no es eficiente en memoria y es más lento en la mayoría de los casos leer más .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,
Responder:
Los lenguajes de programación tienen variables de datos inmutables para que puedan usarse como claves en clave, par de valores. Las variables de cadena se usan como claves / índices, por lo que son inmutables .
fuente
Desde el
Security
punto de vista podemos usar este ejemplo práctico:fuente