Las clases que representan valores deben tener las mismas propiedades que los tipos primitivos. Los tipos primitivos representan valores básicos como int o char en Java. Los tipos primitivos no tienen identidad y son inmutables.

A continuación, veremos que esas propiedades también son útiles para las clases que representan propiedades.

Sin Identidad

Dos valores son iguales si ellos tienen el mismo valor externo visible: Por ejemplo, si tiene dos variables (a y b) con el valor de 5, ellas son iguales:

Inmutable

Los valores son inmutables. Si modifica un valor, se convierte en un nuevo valor. En el siguiente ejemplo, modificamos la variable a, que conduce a un nuevo valor b. Las variables a y b no son iguales.

La clase de Valor A

Ahora veamos una clase que representa un valor con esas dos propiedades, la clase java.time.Instant. Esta clase representa un instante en el tiempo. Veamos primero la declaración de campo de esta clase:

Declarar los campos como final hacen que esta clase sea inmutable. Declarar un campo como final (como los dos campos en el ejemplo) permite al compilador verificar que los campos no se modifiquen después de que se haya llamado al constructor de la clase. Tenga en cuenta que el final es un modificador de campo. Hace que el campo sea inmutable, no el objeto al que hace referencia el campo. Entonces el tipo de campo final también debe ser inmutable o un tipo primitivo como en el ejemplo.

A continuación, veamos el método igual para ver cómo se implementa la igualdad para esta clase:

Tal como se observa, dos objetos Instant son iguales si sus estados externos visibles es igual

Inmutabilidad utiliza la Identidad

Ahora veamos una clase que es inmutable pero usa su identidad para la igualdad: la clase Object. La clase Object es útil cuando solo necesita una identidad pero no un estado, como en el ejemplo siguiente, del JDK 9 java.uti.concurrent.CopyOnWriteArrayList, donde necesitamos la  identidad como monitor para la sincronización:

Representar el valor de una clase con una identidad no es útil.

No Identity pero Mutable

La siguiente muestra una clase valor mutable, la clase java.util.Date:

Los dos campos (cdate y fastTime) no son definitivos y se pueden cambiar con el método setTime, lo que hace que la clase sea mutable. El método igual verifica el estado visible externamente para la igualdad. Si bien es posible implementar valores con clases mutables, las clases inmutables son más fáciles de usar.

Ventajas de una clase Inmutable

Las clases inmutables no pueden cambiar su estado. Esta propiedad es útil en escenarios específicos en programas de sub proceso único, por ejemplo, cuando los usa como claves en mapas hash. Y hace que escribir programas de sub procesos múltiples sea mucho más fácil.

Las clases inmutables no cambian su valor en el medio de una operación sin usar bloques sincronizados. Al evitar los bloques de sincronización, evita los bloqueos. Y como siempre trabajas con un estado constante e inmutable, evitas las condiciones de carrera.

Uso de la Identidad

Si bien aún es posible acceder a la identidad de un objeto de valor, probablemente sea un error. Por ejemplo, el uso de == en lugar de equals es probablemente incorrecto:

Probablemente esperas true cuando comparas dos Integers de valor 5, entonces el valor de  == es incorrecto. Los siguientes métodos utilizan la identidad del objeto y se deben evitar al utilizar el valor de las clases:

  • sentencias de sincronización
  • System.identityHashCode
  • Object.notify and wait

El futuro: JEP 169, Objetos como Valor

La implementación de valores utilizando clases requiere más memoria que sus contrapartes primitivas. Una solución a este problema es implementada por Java Enhancement Proposal 169, Value Objects. Le permitirá crear clases de valor con características de memoria similares a los tipos primitivos.
La idea es implementar un nuevo operador (lockPermanently), que convierte un objeto en un nuevo estado con un consumo de memoria similar a un tipo primitivo. El uso de una operación que requiera la identidad del objeto de valor como == o sincronizado en dicho objeto bloqueado estará prohibido.

Conclusion and What Is Next

Los tipos primitivos representan valores básicos. Los tipos primitivos son inmutables y no tienen identidad. Hemos visto cómo implementar clases con las mismas propiedades. El uso de la identidad de una clase de valor, aunque todavía es posible, es probablemente un error. Hacer que las clases de valor sean inmutables hace que sean más fáciles de usar, especialmente para el software seguro para subprocesos.

Java: Implementación de valores con Clases inmutables
Si te gusto, comparte ...Email this to someone
email
Share on Facebook
Facebook
Tweet about this on Twitter
Twitter
Share on LinkedIn
Linkedin
Share on Google+
Google+
Etiquetado en:    

Un pensamiento en “Java: Implementación de valores con Clases inmutables

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Facebook