¿Es String realmente "inmutable" en Java? (¡Con análisis de código!)

Todos sabemos que el diseño de la clase String en Java es inmutable, echemos un vistazo al código fuente de la clase String.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    .........

}

Se puede ver que la clase String es de tipo final y String no se puede heredar. Su valor es la encapsulación de la matriz de caracteres, es decir, char []. Su valor se define como final privado, lo que significa que no puede ser modificado por el mundo exterior, es decir, es inmutable.

¿Es String realmente "inmutable"?

Considere el siguiente ejemplo:

String str = "hello";
System.out.println(str); // hello

str = "world";
System.out.println(str); // world

str = str.substring(1);
System.out.println(str); // orld

Puede preguntar: ¿No se ha cambiado str de hola a mundo? ¿Entonces se vuelve orld a través del método de subcadena?

En realidad, esto es un malentendido para los principiantes. Si observamos la estructura de String anterior, podemos saber que una cadena se compone de una serie de caracteres. Str es solo una cita. La primera vez que cité "hola", se convirtió en "mundo" más tarde. La subcadena también usa el método Arrays.copyOfRange para volver a copiar la matriz de caracteres para construir una nueva cadena.

image.png

Entonces, la cadena aquí no es mutable, pero se cambia la referencia de la cadena.

¿Es String realmente "inmutable"?

El ejemplo anterior es definitivamente inmutable, pero lo siguiente es vergonzoso:

String str = "Hello world";
System.out.println(str); // Hello world

Field field = String.class.getDeclaredField("value");
field.setAccessible(true);

char[] value = (char[])field.get(str);
value[6] = 'J';
value[7] = 'a';
value[8] = 'v';
value[9] = 'a';
value[10] = '!';
value[11] = '!';
System.out.println(str); // Hello Java!!

A través de la reflexión, cambiamos el valor de la matriz de caracteres subyacente y nos dimos cuenta de la "inmutabilidad" de la cadena. Este es un tipo de operación y no se recomienda su uso. Viola el principio de diseño inmutable de Java para la clase String y causará Algunos problemas de seguridad.

¿Está de nuevo?

Supongo que te gusta

Origin blog.csdn.net/Java_Yhua/article/details/110396898
Recomendado
Clasificación