Esta podría ser la pregunta más tonta que se haya hecho, pero creo que es bastante confuso para un novato en Java.
- ¿Alguien puede aclarar qué se entiende por inmutable ?
- ¿Por qué es un
String
inmutable? - ¿Cuáles son las ventajas / desventajas de los objetos inmutables?
- ¿Por qué debería
StringBuilder
preferirse un objeto mutable como String y viceversa?
Un buen ejemplo (en Java) será realmente apreciado.
java
string
immutability
ashokgelal
fuente
fuente
Respuestas:
Inmutable significa que una vez que el constructor de un objeto ha completado la ejecución, esa instancia no puede modificarse.
Esto es útil ya que significa que puede pasar referencias al objeto alrededor, sin preocuparse de que alguien más vaya a cambiar su contenido. Especialmente cuando se trata de concurrencia, no hay problemas de bloqueo con objetos que nunca cambian
p.ej
Foo
no tiene que preocuparse de que la persona que llamagetValue()
pueda cambiar el texto en la cadena.Si imagina una clase similar a
Foo
, pero con un miembro enStringBuilder
lugar de unString
miembro, puede ver que una persona que llamagetValue()
podría alterar elStringBuilder
atributo de unaFoo
instancia.También tenga cuidado con los diferentes tipos de inmutabilidad que puede encontrar: Eric Lippert escribió un artículo de blog sobre esto. Básicamente, puede tener objetos cuya interfaz es inmutable pero detrás del escenario estado privado de mutables real (y, por lo tanto, no se puede compartir de manera segura entre subprocesos).
fuente
Un objeto inmutable es un objeto donde los campos internos (o al menos, todos los campos internos que afectan su comportamiento externo) no se pueden cambiar.
Las cadenas inmutables tienen muchas ventajas:
Rendimiento: realice la siguiente operación:
La C subyacente para el método substring () es probablemente algo como esto:
¡Tenga en cuenta que ninguno de los personajes tiene que ser copiado! Si el objeto String fuera mutable (los caracteres podrían cambiar más tarde), tendría que copiar todos los caracteres; de lo contrario, los cambios en los caracteres de la subcadena se reflejarían en la otra cadena más adelante.
Concurrencia: si la estructura interna de un objeto inmutable es válida, siempre será válida. No hay posibilidad de que diferentes hilos puedan crear un estado no válido dentro de ese objeto. Por lo tanto, los objetos inmutables son seguros para subprocesos .
Recolección de basura: es mucho más fácil para el recolector de basura tomar decisiones lógicas sobre objetos inmutables.
Sin embargo, también hay inconvenientes en la inmutabilidad:
Rendimiento: ¡ Espera, pensé que dijiste que el rendimiento era una ventaja de la inmutabilidad! Bueno, a veces lo es, pero no siempre. Toma el siguiente código:
Las dos líneas reemplazan el cuarto carácter con la letra "a". El segundo código no solo es más legible, sino que es más rápido. Mira cómo tendrías que hacer el código subyacente para foo. Las subcadenas son fáciles, pero ahora porque ya hay un personaje en el espacio cinco y otra cosa podría estar haciendo referencia a foo, no puedes simplemente cambiarlo; debe copiar toda la cadena (por supuesto, parte de esta funcionalidad se abstrae en funciones en el C subyacente real, pero el punto aquí es mostrar el código que se ejecuta en un solo lugar).
Tenga en cuenta que concatenate se llama dos veces, lo que significa que se debe recorrer toda la cadena. Compare esto con el código C para la
bar
operación:La operación de cadena mutable es obviamente mucho más rápida.
En conclusión: en la mayoría de los casos, desea una cadena inmutable. Pero si necesita agregar e insertar mucho en una cadena, necesita la mutabilidad para la velocidad. Si desea los beneficios de concurrencia de seguridad y recolección de basura, la clave es mantener sus objetos mutables locales a un método:
Como el
mutable
objeto es una referencia local, no tiene que preocuparse por la seguridad de concurrencia (solo un hilo lo toca). Y dado que no se hace referencia en ningún otro lugar, solo se asigna en la pila, por lo que se desasigna tan pronto como finaliza la llamada a la función (no tiene que preocuparse por la recolección de basura). Y obtienes todos los beneficios de rendimiento de mutabilidad e inmutabilidad.fuente
Passing pointers because Java is pass-by-reference
¿No es java "pasar por valor"?En realidad, String no es inmutable si usa la definición de wikipedia sugerida anteriormente.
El estado de la cadena cambia después de la construcción. Eche un vistazo al método hashcode (). La cadena almacena en caché el valor de hashcode en un campo local, pero no lo calcula hasta la primera llamada de hashcode (). Esta evaluación perezosa de hashcode coloca a String en una posición interesante como un objeto inmutable cuyo estado cambia, pero no se puede observar que haya cambiado sin usar la reflexión.
Entonces, tal vez la definición de inmutable debería ser un objeto que no se puede observar que haya cambiado.
Si el estado cambia en un objeto inmutable después de haber sido creado pero nadie puede verlo (sin reflexión), ¿el objeto sigue siendo inmutable?
fuente
Los objetos inmutables son objetos que no se pueden cambiar mediante programación. Son especialmente buenos para entornos de subprocesos múltiples u otros entornos donde más de un proceso puede alterar (mutar) los valores en un objeto.
Sin embargo, solo para aclarar, StringBuilder es en realidad un objeto mutable, no inmutable. Una cadena Java normal es inmutable (lo que significa que una vez que se ha creado no se puede cambiar la cadena subyacente sin cambiar el objeto).
Por ejemplo, supongamos que tengo una clase llamada ColoredString que tiene un valor de cadena y un color de cadena:
En este ejemplo, se dice que ColoredString es mutable porque puede cambiar (mutar) una de sus propiedades clave sin crear una nueva clase ColoredString. La razón por la que esto puede ser malo es, por ejemplo, digamos que tiene una aplicación GUI que tiene múltiples hilos y está usando ColourStrings para imprimir datos en la ventana. Si tiene una instancia de ColouredString que se creó como
Entonces esperarías que la cadena siempre sea "Azul". Si otro hilo, sin embargo, se puso en contacto con esta instancia y llamó
De repente, y probablemente de manera inesperada, ahora tiene una cadena "roja" cuando desea una "azul". Debido a esto, los objetos inmutables son casi siempre preferidos al pasar instancias de objetos alrededor. Cuando tiene un caso en el que los objetos mutables son realmente necesarios, normalmente protegerá el objeto solo pasando copias de su campo de control específico.
Para recapitular, en Java, java.lang.String es un objeto inmutable (no se puede cambiar una vez creado) y java.lang.StringBuilder es un objeto mutable porque se puede cambiar sin crear una nueva instancia.
fuente
Cadena s1 = "Cadena antigua";
Cadena s2 = s1;
s1 = "Nueva cadena";
fuente
"inmutable" significa que no puede cambiar el valor. Si tiene una instancia de la clase String, cualquier método que llame que parezca modificar el valor, en realidad creará otra String.
Para preservar los cambios, debe hacer algo como esto foo = foo.sustring (3);
Inmutable vs mutable puede ser divertido cuando trabajas con colecciones. Piense en lo que sucederá si usa un objeto mutable como clave para el mapa y luego cambie el valor (consejo: piense en
equals
yhashCode
).fuente
java.time
Puede que sea un poco tarde, pero para comprender qué es un objeto inmutable, considere el siguiente ejemplo de la nueva API de fecha y hora de Java 8 ( java.time ). Como probablemente sepa, todos los objetos de fecha de Java 8 son inmutables, así que en el siguiente ejemplo
Salida:
Esto imprime el mismo año que la fecha inicial porque
plusYears(2)
devuelve un nuevo objeto, por lo que la fecha anterior todavía no cambia porque es un objeto inmutable. Una vez creado, no puede modificarlo más y la variable de fecha todavía lo señala.Entonces, ese ejemplo de código debe capturar y usar el nuevo objeto instanciado y devuelto por esa llamada a
plusYears
.fuente
Realmente me gusta la explicación de SCJP Sun Certified Programmer for Java 5 Study Guide .
fuente
Los objetos que son inmutables no pueden cambiar su estado después de haber sido creados.
Hay tres razones principales para usar objetos inmutables siempre que pueda, todas las cuales ayudarán a reducir la cantidad de errores que introduce en su código:
También hay algunas otras optimizaciones que puede hacer en el código cuando sabe que el estado de un objeto es inmutable, por ejemplo, el almacenamiento en caché calculado, pero estas son optimizaciones y, por lo tanto, no son tan interesantes.
fuente
Un significado tiene que ver con cómo se almacena el valor en la computadora. Para una cadena .Net, por ejemplo, significa que la cadena en la memoria no se puede cambiar. Cuando cree que lo está cambiando, de hecho está creando cadena en la memoria y apuntando la variable existente (que es solo un puntero a la colección real de caracteres en otro lugar) a la nueva cadena.
fuente
s1="Hi"
:s1
se creó un objeto con el valor "Hola".s2=s1
:s2
se crea un objeto con referencia al objeto s1.s1="Bye"
: els1
valor del objeto anterior no cambia porques1
tiene el tipo String y el tipo String es un tipo inmutable, en su lugar, el compilador crea un nuevo objeto String con valor "Bye" y haces1
referencia a él. aquí cuando imprimimos els2
valor, el resultado será "Hola", no "Adiós" porque haces2
referencia als1
objeto anterior que tenía el valor "Hola".fuente
Inmutable significa que una vez que se crea el objeto, ninguno de sus miembros cambiará.
String
es inmutable ya que no puede cambiar su contenido. Por ejemplo:En el código anterior, la cadena s1 no cambió,
s2
se creó otro objeto ( ) usandos1
.fuente
Inmutable simplemente significa inmutable o inmodificable. Una vez que se crea el objeto de cadena, sus datos o estado no se pueden cambiar
Considere el siguiente ejemplo,
Vamos a tener una idea considerando el siguiente diagrama,
En este diagrama, puede ver un nuevo objeto creado como "Mundo futuro". Pero no cambia "Futuro".
Because String is immutable
.s
, todavía se refieren a "Futuro". Si necesita llamar "Mundo Futuro",¿Por qué los objetos de cadena son inmutables en Java?
fuente
Una vez instanciado, no puede ser alterado. Considere una clase de la que una instancia podría usarse como clave para una tabla hash o similar. Consulte las mejores prácticas de Java.
fuente
Objetos inmutables
Un objeto se considera inmutable si su estado no puede cambiar después de su construcción. La confianza máxima en objetos inmutables es ampliamente aceptada como una estrategia sólida para crear código simple y confiable.
Los objetos inmutables son particularmente útiles en aplicaciones concurrentes. Como no pueden cambiar de estado, no pueden corromperse por interferencia de hilos ni observarse en un estado inconsistente.
Los programadores a menudo son reacios a emplear objetos inmutables, porque les preocupa el costo de crear un nuevo objeto en lugar de actualizar un objeto en su lugar. El impacto de la creación de objetos a menudo se sobreestima y puede compensarse con algunas de las eficiencias asociadas con los objetos inmutables. Estos incluyen una disminución de la sobrecarga debido a la recolección de basura y la eliminación del código necesario para proteger los objetos mutables de la corrupción.
Las siguientes subsecciones toman una clase cuyas instancias son mutables y derivan de ella una clase con instancias inmutables. Al hacerlo, dan reglas generales para este tipo de conversión y demuestran algunas de las ventajas de los objetos inmutables.
Fuente
fuente
Como la respuesta aceptada no responde todas las preguntas. Me veo obligado a responder después de 11 años y 6 meses.
Espero que haya querido decir objeto inmutable (porque podríamos pensar en una referencia inmutable ).
Un objeto es inmutable : si se crea una vez, siempre representan el mismo valor (no tiene ningún método que cambie el valor).
Respete la definición anterior que se puede verificar buscando en el código fuente de Sting.java .
más seguro de los errores.
Más fácil de entender.
y más listo para el cambio.
Afinando la pregunta ¿Por qué necesitamos el StringBuilder mutable en la programación? Un uso común es concatenar una gran cantidad de cadenas juntas, como esta:
Usando cadenas inmutables, esto hace muchas copias temporales: el primer número de la cadena ("0") se copia n veces en el transcurso de la construcción de la cadena final, el segundo número se copia n-1 veces, y así en. En realidad, cuesta O (n2) tiempo solo para hacer toda esa copia, aunque solo concatenamos n elementos.
StringBuilder está diseñado para minimizar esta copia. Utiliza una estructura de datos interna simple pero inteligente para evitar hacer cualquier copia hasta el final, cuando solicita la Cadena final con una llamada toString ():
Obtener un buen rendimiento es una de las razones por las que usamos objetos mutables. Otro es el uso compartido conveniente: dos partes de su programa pueden comunicarse de manera más conveniente compartiendo una estructura de datos mutable común.
Más se puede encontrar aquí: https://web.mit.edu/6.005/www/fa15/classes/09-immutability/#useful_immutable_types
fuente
Un objeto inmutable es el que no puede modificar después de crearlo. Un ejemplo típico son los literales de cadena.
El lenguaje de programación AD, que se hace cada vez más popular, tiene una noción de "inmutabilidad" a través de la palabra clave "invariante". Consulte este artículo del Dr.Dobb al respecto: http://dobbscodetalk.com/index.php?option=com_myblog&show=Invariant-Strings.html&Itemid=29 . Explica el problema perfectamente.
fuente