Pregunta

¿Todas las clases finales en Java son inmutables? String e Integer son clases finales y ambos son inmutables, creo.

¿Fue útil?

Solución

No: una clase final significa que no puede heredar de ella. No tiene nada que ver con la mutabilidad. La siguiente clase es final pero mutable:

public final class FinalMutable {
  int value;
  public void setValue(int v) { value=v; }
  public int getValue() { return value; }
}

Otros consejos

No, final significa que la clase no se puede extender. No dice nada sobre la mutabilidad. Por ejemplo:

final class MutInt {
   public int modifyMe;
}

No existe una palabra clave para la inmutabilidad, es más como un patrón de diseño.

EDITAR:
Esto significa que no hay una palabra clave que haga que una clase sea inmutable. Para hacer que una clase sea inmutable, debe proteger las partes internas haciéndolas finales o privadas.

Lo confuso es esto: la palabra clave final tiene diferentes significados cuando se usa en una clase que cuando se usa en un campo / variable. El primero significa "esta clase no puede ampliarse". El segundo significa "esta variable (o referencia) no se puede cambiar".

Además de las otras respuestas, si observa el código de java.lang.String verá que contiene un campo: hash , que es mutable y, de hecho, se calcula y almacena cuando se llama a hashCode () por primera vez.

Sin embargo, la clase sigue siendo inmutable : no se puede acceder al campo hash directamente ni modificarlo fuera de la clase.

Además, puede notar que un enfoque común dentro del JDK es la implementación de envoltorios inmutables que pueden usarse para exponer el estado interno de un objeto sin permitir que se modifique; por ejemplo,

private final List<String> values;

public List<? get String> getValues() {
  return Collections.unmodifiableList(values);
}

Como han dicho otros antes, final no hace que una clase sea inmutable en Java, aunque juega un papel en la estrategia de inmutabilidad. Para obtener la inmutabilidad, debe seguir las pautas generales:

  • asegúrese de que la clase no se pueda anular: haga que la clase final , o use fábricas estáticas y mantenga privados a los constructores
  • hacer los campos privados y final
  • obliga a las personas que llaman a construir un objeto completamente en un solo paso, en lugar de usar un constructor sin argumentos combinado con llamadas posteriores a los métodos setXXX (es decir, evitar la convención Java Beans)
  • no proporciona ningún método que pueda cambiar el estado del objeto de ninguna manera, no solo los métodos setXXX , sino cualquier método que pueda cambiar el estado
  • si la clase tiene algún campo de objeto mutable, debe copiarse a la defensiva cuando se pasa entre la clase y su interlocutor

Los métodos anulados de la subclase no pueden acceder al campo privado ... Por lo tanto, no hay forma de que los métodos de la subclase cambien el campo privado de la superclase ... Entonces, ¿de qué sirve hacer que la clase inmutable sea final ?

Las palabras clave finales evitan que las otras clases lo hereden. La palabra clave final no lo hace inmutable, pero existen condiciones tales como hacer que los miembros de la clase de instancia sean privados y finales, y usar getters y no setters

Una clase inmutable final no puede ser mutada. A continuación, se muestra una clase inmutable no final que está siendo mutada:

// a class not intended to be mutated 
public class GoodClass{

   private String name;

   public GoodClass() {
       this.name = "Good Class Neme";
   }

   public String getName() {
       return name;
   }
}

public class BadClass extends GoodClass {

   private String name;

   public String getName() {
       return name;
   }

   // mutating state
   public void setName(String name) {
       this.name = name;
   }
}



Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top