Principalmente creo que la seguridad. Por la misma razón, String es definitivo, cualquier cosa que un código relacionado con la seguridad quiera tratar como inmutable debe ser definitiva.
Supongamos que tiene una clase definida como inmutable, llámela MyUrlClass, pero no la marque como definitiva.
Ahora, alguien podría estar tentado a escribir código de administrador de seguridad como este;
void checkUrl(MyUrlClass testurl) throws SecurityException {
if (illegalDomains.contains(testurl.getDomain())) throw new SecurityException();
}
Y esto es lo que les gustaría poner en su doRequest (MyUrlClass url) Método:
securitymanager.checkUrl(urltoconnect);
Socket sckt = opensocket(urltoconnect);
sendrequest(sckt);
getresponse(sckt);
Pero no pueden hacer esto, porque usted no hizo MyUrlClass final. La razón por la que no pueden hacerlo es que, si lo hicieran, el código podría evitar las restricciones del administrador de seguridad al anular getDomain() para que devuelva "www.google.com" la primera vez que se llame y "www.evilhackers.org". el segundo, y pasar un objeto de su clase a DoRequest().
tengo nada en contra de evilhackers.org, por cierto, si es que existe ...
En ausencia de problemas de seguridad es todo acerca de cómo evitar los errores de programación, y es, por supuesto, depende de cómo se Haz eso. Las subclases deben mantener el contrato de sus padres, y la inmutabilidad es solo una parte del contrato. Pero si se supone que las instancias de una clase son inmutables, entonces hacer que sea definitiva es una buena forma de asegurarse de que realmente sean inmutables (es decir, que no haya instancias mudables de subclases dando vueltas, que pueden usarse en cualquier lugar donde el padre clase es requerida).
No creo que el artículo al que hace referencia deba tomarse como una instrucción de que "todas las clases inmutables deben ser definitivas", especialmente si tiene un motivo positivo para diseñar su clase inmutable para la herencia. Lo que estaba diciendo es que proteger la inmutabilidad es una razón válida para el final, donde las preocupaciones de rendimiento imaginario (que es de lo que realmente se habla en ese momento) no son válidas. Tenga en cuenta que dio "una clase compleja no diseñada para la herencia" como una razón igualmente válida. Se puede argumentar de manera justa que no tener en cuenta la herencia en las clases complejas es algo que se debe evitar, así como no tener en cuenta la herencia en las clases inmutables. Pero si no puede explicarlo, al menos puede señalar este hecho previniéndolo.
Pero es posible que desee extender una clase inmutable para agregar propiedades adicionales de Immutbale. –
"Porque si la clase es definitiva no puede extenderla y hacerla mutable" Pero no puede extender una clase inmutable no final y hacerla mutable, solo puede hacer que la subclase mutable –
Como llamante, no sabe si está utilizando la clase inmutable o su subclase mutable, a menos que llame al constructor directamente. Eso es polimorfismo. – slim