1. Introducción a categorías inmutables
Clase inmutable: la llamada clase inmutable significa que una vez que se crea una instancia de esta clase, su valor variable miembro no se puede cambiar. Por ejemplo, muchas clases inmutables que vienen con JDK: Interger, Long and String, etc.
Clases variables: en comparación con las clases inmutables, las clases mutables pueden cambiar sus valores variables miembros después de crear instancias. La mayoría de las clases creadas en el desarrollo pertenecen a clases mutables.
2. Ventajas de clases inmutables
Después de hablar sobre la diferencia entre clases mutables y clases inmutables, ¿debemos entender más por qué hay clases inmutables? ¿Qué beneficios aporta tal característica a Java?
1. Seguridad del hilo
Los objetos inmutables son seguros y se pueden compartir entre hilos. No es necesario usar mecanismos especiales para garantizar problemas de sincronización, porque el valor del objeto no se puede cambiar. Puede reducir la posibilidad de errores concurrentes, porque no es necesario usar algunos mecanismos de bloqueo para garantizar problemas de consistencia de la memoria, lo que también reduce la sobrecarga de sincronización.
2. Fácil de construir, usar y probar
3 ....
Método de diseño de clase inmutable
Para las clases inmutables de diseño, resumo personalmente los siguientes principios:
1. Agregue un modificador final a la clase para asegurarse de que la clase no esté heredada.
Si se puede heredar una clase, destruirá el mecanismo de inmutabilidad de la clase, siempre que la clase de herencia anule los métodos de la clase principal y la clase de herencia puede cambiar el valor variable del miembro, entonces una vez que la clase infantil aparece como la clase principal, no se puede garantizar si la clase actual es mutable.
2. Asegúrese de que todas las variables de los miembros sean privadas y se agregan modificaciones finales
De esta manera, asegura que las variables de los miembros sean inmutables. Pero no es suficiente hacer esto, porque si se trata de una variable de miembro del objeto, es posible cambiar su valor externamente. Entonces, el cuarto punto compensa esta deficiencia.
3. No se proporcionan métodos para cambiar las variables de los miembros, incluidos los setters
Evite cambiar el valor de las variables miembros a través de otras interfaces y destruir características inmutables.
4. Inicialice a todos los miembros a través del constructor y realice una copia profunda (copia profunda)
Si el objeto aprobado por el constructor se asigna directamente a la variable miembro, aún se puede cambiar modificando el objeto entrante, lo que provocará que se cambie el valor de la variable interna. Por ejemplo:
Public Final Class ImmutableMo {private final int [] myArray; public ImmutableMo (int [] array) {this.myArray = array; // equivocado } }Este método no puede garantizar la inmutabilidad. MyArray y la matriz apuntan a la misma dirección de memoria. Los usuarios pueden cambiar el valor dentro de MyArray modificando el valor del objeto de matriz fuera de ImmutableMo.
Para garantizar que el valor interno no se modifique, se puede usar una copia de profundidad para crear una nueva memoria para guardar el valor entrante. Forma correcta de hacerlo:
Public Final Class MyImmUtableMo {private final int [] myArray; public MyImmUtableMo (int [] array) {this.myArray = array.clone (); }}5. En el método Getter, no devuelva el objeto en sí mismo directamente, pero clone el objeto y devuelva la copia del objeto.
Este enfoque también previene la fuga de objetos y previene la operación directa de las variables miembros después de obtener objetos miembros mutables internos a través de Getters, lo que resulta en cambios en las variables miembros.
IV. Inmutabilidad de los objetos de cadena
El objeto de cadena no se puede cambiar después de la creación de memoria. La creación de objetos inmutables generalmente cumple con los 5 principios anteriores. Echemos un vistazo a cómo se implementa el código de cadena.
Public Final Class StringImplements java.io.Serializable, comparable <String>, CharSequence {/** El valor se usa para el almacenamiento de caracteres. */valor de char final privado [];/** El desplazamiento es el primer índice del almacenamiento que se utiliza. */private final int offset;/** El recuento es el número de caracteres en la cadena. */private final int count;/** caché El código hash para la cadena*/private int hash; // predeterminado a 0..Public String (Char Value []) {this.value = arrays.copyOf (value, value.length); // Operación de copia profunda} ... public char [] toCarArray () {// No se puede usar matrices.copyOf debido a los problemas de orden de inicialización de clase Resultado [] = new Char [value.length]; system.arrayCopy (valor, 0, resultado, 0, value.length); return;} ...} ...}Como se muestra en el código anterior, se pueden observar los siguientes detalles de diseño:
1. La clase de rayos se modifica por final y no se puede heredar
2. Todos los miembros de la cadena se establecen como variables privadas
3. El valor de valor no existe
4. Y establecer valor y compensación en final.
5. Al pasar por un valor de matriz de variable [], copie en lugar de copiar el valor [] directamente a la variable interna.
6. Al obtener el valor, no devuelve directamente la referencia del objeto, sino que devuelve la copia del objeto.
Esto es consistente con las características del tipo invariante resumido anteriormente, y también asegura que el tipo de cadena sea una clase inmutable.
5. Ventajas y desventajas de la inmutabilidad de los objetos de cadena
Del análisis de la sección anterior, los datos de la cadena son inmutables, entonces, ¿cuáles son los beneficios de establecer dicha característica? Lo resumí de la siguiente manera:
1. Requisitos para grupos constantes de cadena.
Las piscinas constantes de cadena pueden reutilizar algunas constantes de caracteres en la piscina constante, evitando recrear el mismo objeto cada vez y ahorrar espacio de almacenamiento. Pero si la cadena es variable, la cadena del mismo contenido también apunta al mismo espacio de memoria del grupo constante. Cuando una variable cambia el valor de esa memoria, los otros valores atravesados también cambiarán. Por lo tanto, no se ajusta a la intención original del diseño constante de la piscina.
2. Consideraciones de seguridad del hilo.
La misma instancia de cadena se puede compartir mediante múltiples hilos. De esta manera, no hay necesidad de usar la sincronización debido a problemas de seguridad del hilo. Las cadenas son seguras de hilo.
3. Los cargadores de clases deben usar cadenas, y la inmutabilidad proporciona seguridad para que se cargue la clase correcta. Por ejemplo, si desea cargar la clase Java.sql.connection y este valor se cambia a myhacked.connection, causará daños desconocidos en su base de datos.
4. Apoyo al mapeo y almacenamiento en caché del hash.
Debido a que las cadenas son inmutables, el hashcode se almacena en caché cuando se crea y no necesita ser recalculado. Esto hace que las cadenas sean muy adecuadas como claves en el mapa, y la velocidad de procesamiento de las cadenas es más rápida que otros objetos clave. Esta es la razón por la cual las claves en hashmap a menudo usan cadenas.
defecto:
1. Si es necesario cambiar el valor del objeto de cadena, se creará una gran cantidad de objetos de cadena.
6. ¿El objeto de cadena es realmente inmutable?
Aunque el objeto de cadena establece el valor en final, también garantiza que sus variables miembros sean inmutables a través de varios mecanismos. Sin embargo, todavía se puede cambiar a través del mecanismo de reflexión. Por ejemplo:
// Cree la cadena "Hello World" y asigna a la referencia SSTRING S = "Hello World"; System.out.println ("S =" + S); // Hola Mundo // Obtener el campo Valor en la clase String Class Field GaleFieldOfString = String.Class.GetDeclaredField ("Valor"); // Cambie el permiso de acceso de la Value Atributo valiente de valuefieldOfString.SetAccessible (verdadero); // Obtenga el valor del atributo de valor en el valor S Object [] Valor = (Char []) valientefieldOfString.get (s); // Cambiar el 5th Carpil Value en el Valor de Objeto s REFERTAR = (Char []) = '_'; System.out.println ("S =" + S); //Hola MundoEl resultado de la impresión es:
S = Hello Worlds = Hello_World
Se descubrió que el valor de la cadena ha cambiado. Es decir, el llamado objeto "inmutable" se puede modificar a través de la reflexión.
Resumir
Una clase inmutable es el valor del recorrido miembro que no se puede cambiar después de que se crea la instancia. Esta característica permite que las clases inmutables proporcionen características seguras de hilo, pero también aporta la creciente creación de objetos. Cada cambio de atributo es recrear un nuevo objeto. JDK también proporciona muchas clases inmutables como entero, doble, cadena, etc. Las características inmutables de la cadena son principalmente para satisfacer las necesidades de agrupación constante, seguridad de hilos y carga de clase. El uso racional de clases inmutables puede traer grandes beneficios.
Lo anterior es el mecanismo inmutable de la Java (inmutable) y la inmutabilidad de la cadena (recomendada) presentada por el editor. Espero que te sea útil. Si tiene alguna pregunta, déjame un mensaje y el editor le responderá a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!