¿Cuándo y por qué usaríamos punteros inmutables?

7

En Java, el objeto String es inmutable y también un puntero (también conocido como tipo de referencia). Estoy seguro de que hay otros tipos / objetos que son inmutables y también un puntero y que esto se extiende más allá de solo Java.

No puedo pensar en dónde sería deseable, posiblemente debido a mi propia experiencia. Solo he usado tipos de referencia O tipos primitivos inmutables.

¿Puede alguien darme una situación en la que sería útil para poder apreciar su significado / valor / concepto?

    
pregunta Dave 15.03.2013 - 16:00

5 respuestas

9

Un tipo de referencia inmutable se comporta de manera similar a un tipo de valor .

Si String no fuera inmutable, algo como esto podría suceder:

String a = "abc";
String b = a;
a.ReplaceCharAt(1, "X");  // this is not possible, if the type is immutable

// b is now "aXc", which might be counter-intuitive

La inmutabilidad evita que esto suceda: cada vez que asigno una cadena a una variable, puedo estar seguro de que esta cadena no cambiará hasta que reasigne la variable.

Por otro lado, todavía obtenemos los beneficios de los tipos de referencia para String :

  • En el ejemplo anterior, abc solo se almacenaría una vez en la memoria.
  • Las cadenas pueden ser de tamaño variable.

La última es probablemente la razón principal por la que las cadenas son tipos de referencia en Java y .NET. A menudo , tipos de valor se almacenan en la pila. Para poner algo en la pila, el compilador necesita saber su tamaño de antemano, lo que es un poco difícil para cadenas de diferentes tamaños.

    
respondido por el Heinzi 15.03.2013 - 16:08
36

Primero, consideremos por qué es útil tener cadenas que sean inmutables. Considere el siguiente boceto:

void Safe(string s)
{
    if (!SecurityCheck(s)) { throw new SecurityException(); }
    Dangerous(s);
}

El método Safe verifica si la cadena s es "segura". Quizás con "seguro" queremos decir "el usuario tiene permiso para acceder a esta tabla de base de datos", o "la cadena no contiene HTML que pueda usarse en un ataque de scripts entre sitios", o lo que sea. Solo si la cadena es segura se pasa a un método que hace algo peligroso con ella.

Si las cadenas eran mutables, un atacante inteligente podría pasar una cadena "segura" y luego después del control de seguridad , mutar la cadena en una cadena "peligrosa". Obtener el tiempo correcto puede ser complicado, pero, por supuesto, los atacantes pueden intentarlo varias veces, y solo tienen que tener éxito una vez.

Esto ilustra el primer valor de los datos inmutables: los hechos deducidos en el pasado sobre los datos se mantienen en el futuro . Si tiene una cola inmutable y pregunta cuántos elementos hay en ella, la respuesta que obtuvo hace cinco mil nanosegundos sigue siendo correcta . Esto le permite realizar cálculos con confianza.

El segundo gran valor de los datos inmutables es que habilita persistencia . Por persistencia no me refiero a la capacidad de serializar en disco (aunque eso es práctico), sino a la capacidad de para reutilizar una parte de una estructura de datos cuando se construye una estructura de datos más grande . Si tiene un árbol inmutable grande y desea que sea un subárbol de un árbol más grande, no hay problema. Usted sabe que no va a cambiar, por lo que puede compartir los datos de forma segura. Pero si tiene, digamos, una cola mutable y le gustaría usar su contenido en otra estructura de datos, tendrá que hacer una copia.

Eso es sólo un breve boceto; Vea mi serie de artículos sobre estructuras de datos inmutables para más detalles:

enlace

    
respondido por el Eric Lippert 17.03.2013 - 16:38
5

Ahh ... la cadena bendita, es el fotón del mundo del software. Dependiendo de cómo se mire, muestra propiedades de un tipo de referencia o un tipo de valor.

El beneficio de ser un tipo de referencia es que puede pasarlo por referencia. Pero si declaré una cadena como "MyConstantValueString" y la pasé a una función, no querría que esa función cambie el valor porque siempre espero que sea "MyConstantValueString".

Al hacerlo inmutable, obtiene los beneficios de pasar por referencia (no se necesita copia) con la seguridad de saber que la cadena a la que apunta nunca cambiará a menos que la apunte explícitamente a otra.

Hay otros escenarios en los que esto será útil. Piense, por ejemplo, en una cola funcional. Para referencia, le señalo la excelente trabajo de Eric Lippert (está en C # pero es bastante fácil de traducir a Java, y recomiendo leer toda la serie, es bastante revelador). ¿Dónde querría usar una cola funcional y qué uso sería?

Lo creas o no, las colas funcionales son útiles para ... poner en cola. P.ej. Tengo trabajo que debo hacer, necesito permitir que los clientes agreguen trabajo por hacer, al mismo tiempo que les permita a los trabajadores realizar el trabajo y hacerlo. Internamente, la cola es inmutable con un solo escritor y lector interno. Externamente, puedo evitar la sincronización con solo decirle al escritor que agregue mi trabajo a la cola y seguir adelante. Mientras tanto, el lector puede extraer un lote de artículos y distribuirlos a los trabajadores también de forma asíncrona. Esto reduce tremendamente los cuellos de botella. De hecho, así es como se estructura ZeroMQ .

    
respondido por el Michael Brown 15.03.2013 - 16:20
1

Una cadena es un puntero que apunta a un objeto inmutable. El puntero en sí no es inmutable. Los cambios en las cadenas se realizan cambiando el puntero para que apunte a un nuevo objeto inmutable.

Las cadenas son inmutables precisamente de modo que una variable que en realidad es un puntero se puede tratar como una variable normal, en lugar de un puntero.

Debido a que las cadenas son inmutables, un objeto de cadena (es decir, un puntero) se puede pasar, sin preocuparse de si la cosa a la que apunta cambiará. Ese es el beneficio del sistema.

    
respondido por el user82096 15.03.2013 - 16:08
0

Tu pregunta me dice que realmente debes leer Effective Java de Joshua Bloch. La primera edición está disponible en línea como PDF de forma gratuita, por ejemplo here as PDF (nota: especialmente el capítulo de singleton está desactualizado y faltan otras cosas nuevas, así que considere obtener la segunda edición si le gusta el libro). Todos los programadores de Java, incluso los experimentados, que aún no lo hayan hecho deberían revisar los elementos del libro al menos de un vistazo y estudiar detenidamente todo lo que aún no saben.

En 1ª ed. El ítem 13 en el Capítulo 4 es el título "Favorecer la inmutabilidad" y trata el tema con mayor extensión de lo que es razonable en una respuesta aquí. Pero en resumen, debería preguntarse por qué hay tipos de referencia que no son inmutables. Lista corta de beneficios de la inmutabilidad: simple de múltiples maneras, inherentemente segura para subprocesos.

El único inconveniente de los objetos inmutables es: si desea cambiar alguna propiedad del objeto inmutable, debe crear un nuevo objeto, como hace el fragmento de código String s=""; s=s+5; : primero tiene una instancia de cadena vacía, luego crea una nueva instancia de cadena con valor %código%). Además, los singletons que tienen un estado cambiante no pueden ser inmutables, por razones obvias.

    
respondido por el hyde 17.03.2013 - 18:44

Lea otras preguntas en las etiquetas