que - ¿Por qué String es inmutable en Java?
por que string es inmutable (12)
Me preguntaron en una entrevista por qué String es inmutable
Respondí así:
Cuando creamos una cadena en java como
String s1="hello";
luego se creará un objeto en el grupo de cadenas (hello) y s1 apuntará a hola . Ahora, si de nuevo hacemosString s2="hello";
entonces no se creará otro objeto, pero s2 apuntará ahello
porque JVM primero comprobará si el mismo objeto está presente en el grupo de cadenas o no. Si no está presente, solo se creará uno nuevo else no.
Ahora, supongamos que java permite la cadena mutable, entonces si cambiamos s1 a hello world
entonces el valor de s2 también será hello world
por lo que java String es inmutable.
¿Puede algún cuerpo decirme si mi respuesta es correcta o incorrecta ?
Cadena se da como inmutable por Sun micro sistemas, porque la cadena se puede utilizar 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 del mapa
Desde el punto de vista de la Security
, podemos usar este ejemplo práctico:
DBCursor makeConnection(String IP,String PORT,String USER,String PASS,String TABLE) {
// if strings were mutable IP,PORT,USER,PASS can be changed by validate function
Boolean validated = validate(IP,PORT,USER,PASS);
// here we are not sure if IP, PORT, USER, PASS changed or not ??
if (validated) {
DBConnection conn = doConnection(IP,PORT,USER,PASS);
}
// rest of the code goes here ....
}
La cadena es inmutable porque:
1. Diseño: - El grupo de cadenas solo es posible porque String es inmutable en Java, de esta manera Java Runtime ahorra mucho espacio en el montón de Java porque diferentes variables de Cadena pueden hacer referencia a la misma variable de Cadena en el grupo. Si String no hubiera sido inmutable, la interna de String no hubiera sido posible porque si alguna variable hubiera cambiado el valor, también se habría reflejado a otras variables.
2. Seguridad: - Si Cadena no es inmutable, causaría una amenaza grave a la seguridad de la aplicación. Por ejemplo, el nombre de usuario de la base de datos, la contraseña se pasan como String para obtener la conexión de la base de datos y en la programación del socket los detalles del host y del puerto pasados como String. Dado que String es inmutable, su valor no se puede cambiar; de lo contrario, cualquier hacker podría cambiar el valor al que se hace referencia para causar problemas de seguridad en la aplicación.
3. Thread Safe: Dado que String es inmutable, es seguro para multihebras y una sola instancia de String se puede compartir a través de diferentes subprocesos. Esto evita el uso de la sincronización para la seguridad del hilo, las cadenas son implícitamente thread safe
4. classloader: - Las cadenas se utilizan en el cargador de clases java y la inmutabilidad proporciona seguridad de que Classloader está cargando la clase correcta. Por ejemplo, piense en una instancia en la que intente cargar la clase java.sql.Connection, pero el valor al que se hace referencia se cambia a la clase myhacked.Connection que puede hacer cosas no deseadas en su base de datos.
5. Almacenamiento en caché: - Dado que String es inmutable, su código hash se almacena en caché en el momento de la creación y no es necesario volver a calcularlo. Esto lo convierte en un gran candidato para la clave en un Mapa y su procesamiento es más rápido que otros objetos clave de HashMap. Esta es la razón por la cual String se usa principalmente como Objeto como teclas HashMap. Arriba están algunas de las razones que podría pensar que muestran los beneficios de la inmutabilidad de la secuencia. Es una gran característica de la clase Java String y lo hace especial.
La clase de cadena es FINAL
significa que no puede crear ninguna clase para heredarla y cambiar la estructura básica y hacer que Sting sea mutable.
Otra variable de instancia thing y los métodos de la clase String que se proporcionan son tales que no puede cambiar String
objeto String
una vez creado.
La razón por la que ha agregado no hace que el String sea inmutable. Esto dice que el String se almacena en heap. El grupo de cadenas también hace una gran diferencia en el rendimiento
La razón más importante de acuerdo con this artículo sobre DZone:
String Constant Pool ... Si string es mutable, cambiar la cadena con una referencia dará lugar a un valor incorrecto para las otras referencias.
Seguridad
String se usa ampliamente como parámetro para muchas clases de Java, por ejemplo, conexión de red, archivos de apertura, etc. Si String no fuera inmutable, una conexión o archivo se cambiaría y conllevaría una grave amenaza a la seguridad. ...
Espero que te ayude.
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 grupo de cadenas, se derivan del hecho de que String in se hizo inmutable. Por ej. String Pool podría ser creado porque String era inmutable y no al revés.
Revisa la transcripción de la entrevista de Gosling here
Desde un punto de vista estratégico, tienden a ser más a menudo libres de problemas. Y generalmente hay cosas que puedes hacer con inmutables que no puedes hacer con cosas mutables, como el resultado de la caché. Si pasa una cadena a un método de abrir archivo, o si pasa una cadena a un constructor para una etiqueta en una interfaz de usuario, en algunas API (como en muchas de las API de Windows) transfiere una matriz de caracteres. El receptor de ese objeto realmente tiene que copiarlo, porque no sabe nada sobre el tiempo de vida de almacenamiento de la misma. Y ellos no saben lo que le está sucediendo al objeto, ya sea que lo estén cambiando bajo sus pies.
Al final, casi te obligan a replicar el objeto porque no sabes si lo posees o no. Y una de las cosas buenas de los objetos inmutables es que la respuesta es: "Sí, por supuesto que sí". Porque la cuestión de la propiedad, quién tiene el derecho de cambiarla, no existe.
Una de las cosas que obligó a Strings a ser inmutable fue la seguridad. Tienes un método de abrir archivo. Usted le pasa una Cadena. Y luego está haciendo todo tipo de comprobaciones de autenticación antes de hacer la llamada al sistema operativo. Si consigues hacer algo que efectivamente mutó el String, después del control de seguridad y antes de la llamada del sistema operativo, entonces boom, estás dentro. Pero las cadenas son inmutables, por lo que ese tipo de ataque no funciona. Ese ejemplo preciso es lo que realmente exigió que las cadenas fueran inmutables
La razón principal es sobre seguridad
Muchas contraseñas, infos de conexión db y parámetros importantes se envían usando "Cadena".
Leí esta publicación Why String is Immutable o Final en Java y supongo que el siguiente puede ser el motivo más importante:
String es inmutable en Java porque los objetos String están en caché en String pool . Como los literales String en caché se comparten entre varios clientes, siempre hay un riesgo, donde la acción de un cliente afectaría a todos los demás clientes.
Los desarrolladores de Java deciden que las cadenas son inmutables debido a los siguientes aspectos de diseño, eficiencia y seguridad .
Las cadenas de diseño se crean en un área de memoria especial en el montón de Java conocido como "Grupo interno de cadenas". Mientras crea una cadena nueva (no en el caso de usar el constructor String () o cualquier otra cadena que use internamente el constructor String () para crear un nuevo objeto String; String () constructor siempre crea una nueva constante de cadena en la agrupación a menos que llamar a la variable method intern() ) busca en el grupo para verificar si ya existe. Si es existente, devuelve la referencia del objeto String existente. Si la Cadena no es inmutable, cambiar la Cadena con una referencia dará lugar a un valor incorrecto para las otras referencias.
De acuerdo con this artículo sobre DZone:
Security String se usa ampliamente como parámetro para muchas clases de Java, por ejemplo, conexión de red, archivos de apertura, etc. Si String no fuera inmutable, una conexión o archivo se cambiaría y podría ocasionar serias amenazas de seguridad. Las cadenas mutables también pueden causar problemas de seguridad en Reflection, ya que los parámetros son cadenas.
Eficiencia El hashcode de cadena se usa frecuentemente en Java. Por ejemplo, en un HashMap. Al ser inmutable, garantiza que hashcode siempre será el mismo, de modo que se pueda almacenar en caché sin preocuparse por los cambios. Esto significa que no es necesario calcular el código hash cada vez que se utiliza.
No podemos estar seguros de lo que los diseñadores de Java realmente pensaron al diseñar String
pero solo podemos concluir estas razones en función de las ventajas que obtenemos de la inmutabilidad de las cadenas, algunas de las cuales son
1. Existencia de grupo constante de cadenas
Como se discutió en Why String se almacena en el artículo String Constant Pool , cada aplicación crea demasiados objetos de cadena y para salvar a JVM de crear primero muchos objetos de cadena y luego recolectarlos. JVM almacena todos los objetos de cadena en un área de memoria separada llamada conjunto de constante de cadena y reutiliza los objetos de ese grupo en caché.
Siempre que creamos una cadena, la JVM literal ve primero si ese literal ya está presente en el grupo constante o no, y si está allí, la referencia nueva comenzará a apuntar al mismo objeto en SCP.
String a = "Naresh";
String b = "Naresh";
String c = "Naresh";
En el ejemplo anterior, el objeto cadena con valor Naresh
se creará en SCP solo una vez y todas las referencias a
, b
, c
apuntarán al mismo objeto, pero ¿qué a.replace("a", "")
si intentamos hacer cambios en, por ejemplo, a.replace("a", "")
Idealmente, a
debe tener valor Nresh
pero b
, c
debe permanecer sin cambios porque como usuario final estamos haciendo el cambio de a
única. Y sabemos que a
, b
, c
todos apuntan al mismo objeto, por lo que si hacemos un cambio en a
, otros también deberían reflejar el cambio.
Pero la inmutabilidad de las cuerdas nos salva de este escenario y, debido a la inmutabilidad del objeto de cadena de objetos de cadena, Naresh
nunca cambiará. Entonces, cuando hacemos un cambio en a
en lugar de cambiar el objeto de cadena, Naresh
JVM crea un nuevo objeto, lo asigna a a
y luego realiza un cambio en ese objeto.
Así que String Pool solo es posible debido a la inmutabilidad de String y si String no hubiera sido inmutable, entonces el almacenamiento en caché de objetos de cadena y su reutilización no tendría una posibilidad porque cualquier variable habría cambiado el valor y corrompido a otros.
Y es por eso que es manejado por JVM muy especialmente y se les ha dado un área de memoria especial.
2. Seguridad de subprocesos
Un objeto se denomina seguro para subprocesos cuando varios subprocesos están operando en él, pero ninguno de ellos puede dañar su estado y el objeto mantiene el mismo estado para cada subproceso en cualquier momento.
Como 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 por defecto. No es necesario que apliquemos medidas de seguridad de hilos, como la creación de métodos sincronizados.
Por lo tanto, 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, tenemos que pasar varios secretos, por ejemplo, nombre de usuario / contraseñas, URL de conexión y, en general, toda esta información se pasa como el objeto de cadena.
Supongamos ahora que si String no hubiera sido inmutable en su naturaleza, se produciría una amenaza grave a la seguridad de la aplicación porque se permite cambiar estos valores y, si está permitido, podrían cambiar debido a un código escrito erróneamente o a cualquier otra persona que tener acceso a nuestras referencias variables
4. Carga de clase
Como se discutió en Creación de objetos a través de Reflection en Java con Example , podemos usar el método Class.forName("class_name")
para cargar una clase en la memoria que de nuevo llama a otros métodos para hacerlo. E incluso JVM usa estos métodos para cargar clases.
Pero si ve claramente todos estos métodos acepta el nombre de clase como un objeto de cadena, de modo que las cadenas se utilizan en la carga de la clase java y la inmutabilidad proporciona seguridad de que ClassLoader
está cargando la clase correcta.
Supongamos que String no hubiera sido inmutable y estamos tratando de cargar java.lang.Object
que se cambió a org.theft.OurObject
y ahora todos nuestros objetos tienen un comportamiento que alguien puede usar para cosas no deseadas.
5. Almacenamiento en caché HashCode
Si vamos a realizar operaciones relacionadas con hash en cualquier objeto, debemos anular el método hashCode()
e intentar generar un hashcode preciso utilizando el estado del objeto. Si el estado del objeto cambia, lo que significa que su código hash también debe cambiar.
Debido a que String es inmutable, el valor que un objeto de cadena mantiene nunca se cambiará, lo que significa que su código hash tampoco cambiará, lo que 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 hashcode en el momento de la creación del objeto, lo que lo convierte en el gran candidato para las operaciones relacionadas con el hashing porque el hashcode no necesita calcularse nuevamente, lo que nos ahorra algo de tiempo. Esta es la razón por la cual String se usa principalmente como teclas HashMap
.
Lea más sobre Por qué String es inmutable y final en Java .
Tienes razón. String
in java usa el concepto de literal String Pool
. 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 a un valor incorrecto para las otras referencias.
Agregaría una cosa más, ya que String
es inmutable, es seguro para múltiples subprocesos y una única instancia de String se puede compartir en diferentes subprocesos. Esto evita el uso de la sincronización para la seguridad del hilo, las cadenas son implícitamente thread safe
.
String
es inmutable por varias razones, aquí hay un resumen:
- Seguridad : los parámetros se representan típicamente como
String
en las conexiones de red, URL de conexión a la base de datos, nombres de usuario / contraseñas, etc. Si fueran mutables, estos parámetros podrían cambiarse fácilmente. - Sincronización y concurrencia: al hacer que Cadena inmutable automáticamente los hace seguros, resuelve los problemas de sincronización.
- Almacenamiento en caché : cuando el compilador optimiza los objetos String, ve que si dos objetos tienen el mismo valor (a = "prueba" yb = "prueba") y necesita solo un objeto de cadena (para a y b, estos dos señalar el mismo objeto).
- Carga de clase : la
String
se utiliza como argumentos para la carga de clase. Si es mutable, podría dar lugar a que se cargue una clase incorrecta (porque los objetos mutables cambian su estado).
Dicho esto, la inmutabilidad de String
solo significa que no puedes cambiarlo usando su API pública. De hecho, puede eludir la API normal mediante el reflejo. Vea la respuesta here .
En su ejemplo, si String
fue mutable, considere el siguiente ejemplo:
String a="stack";
System.out.println(a);//prints stack
a.setValue("overflow");
System.out.println(a);//if mutable it would print overflow