A menudo lee sobre objetos inmutables que requieren que los campos finales sean inmutables en Java. ¿Es este el caso, o es simplemente suficiente para no tener mutabilidad pública y no mutar realmente el estado?¿Los campos deben ser explícitamente definitivos para tener un objeto inmutable "adecuado"?
Por ejemplo, si tiene un objeto inmutable construido por el patrón del constructor, puede hacerlo haciendo que el constructor asigne los campos individuales a medida que se construye o haciendo que el constructor contenga los campos y finalmente devuelva el objeto inmutable pasando los valores a su constructor (privado).
Tener los campos finales tiene la ventaja obvia de evitar errores de implementación (como permitir que el código retenga una referencia al constructor y "construir" el objeto varias veces mientras muta un objeto existente), pero tener el almacén de compilación sus datos dentro del objeto tal como está construido parecerían ser DRYer.
Así que la pregunta es: suponiendo que el generador no pierde el objeto temprano y se detiene a sí mismo de modificar el objeto una vez construido (por ejemplo, estableciendo su referencia al objeto como nulo) ¿hay algo ganado (como seguridad de hilo mejorado)) en la "inmutabilidad" del objeto si los campos del objeto se hicieron finales en su lugar?
Si no me equivoco * final * también puede ayudar a prevenir contra los "ataques de reflexión" donde un programador deshonesto usaría la reflexión para acceder a los campos de su clase y modificar su contenido. Hubo un famoso ejemplo que pervirtió completamente la clase * String * y demostró que en muchos casos * String * en realidad podría ser modificado (si no es debido a no-finalness por cierto, pero debido al hecho de que una vez el subyacente * char [] * se accedió si se había "terminado el juego" porque no se puede forzar la inmutabilidad en el contenido de una matriz ... Pero ese no es mi punto: mi punto es que la reflexión puede ayudar a hacer cosas realmente desagradables). – TacticalCoder
@user, frente a un reflejo como ese, no se puede establecer la inmutabilidad. Sin embargo, Security Manager se trata de hacer que ejecutar código de terceros sea viable. – Yishai
espera ... Si tengo una clase * final * con una * int * final única, ¿puede modificarla utilizando la reflexión? Mi punto era precisamente que * sin * usar * final * no puedes evitar los ataques de reflexión (a menos que tengas un * Security Manager * en su lugar, pero casi nunca es el caso, por eso escribí * "en muchos casos puede ser modificado"*...). Sin embargo, no estoy seguro de que pueda usar la reflexión para modificar una * int final ... ... Si no puede, mi comentario es bastante sobre el tema con su pregunta:) (Hice +1 su pregunta ayer por cierto:) – TacticalCoder