tipos primitivos objeto ejemplos datos java primitive

primitivos - tipos de variables en java ejemplos



¿Los primitivos de Java son inmutables? (5)

Si un método tiene una variable local i :

int i = 10;

y luego asigno un nuevo valor:

i = 11;

¿Esto asignará una nueva ubicación de memoria? ¿O simplemente reemplaza el valor original?

¿Significa esto que los primitivos son inmutables?


¿Esto asignará una nueva ubicación de memoria? ¿O simplemente reemplaza el valor original?

Java realmente no garantiza que las variables correspondan a las ubicaciones de memoria; por ejemplo, su método podría estar optimizado de tal forma que i esté almacenado en un registro, o incluso que no pueda almacenarse, si el compilador puede ver que en realidad nunca usa su valor, o si puede rastrearlo a través del código. y use los valores apropiados directamente.

Pero dejando eso de lado. . . si tomamos la abstracción aquí para que una variable local denote una ubicación de memoria en la pila de llamadas, entonces i = 11 simplemente modificará el valor en esa ubicación de memoria. No necesitará usar una nueva ubicación de memoria, porque la variable i era lo único que se refería a la ubicación anterior.

¿Significa esto que los primitivos son inmutables?

Sí y no: sí, los primitivos son inmutables, pero no, eso no se debe a lo anterior.

Cuando decimos que algo es mutable, queremos decir que puede ser mutado: cambiado sin dejar de tener la misma identidad. Por ejemplo, cuando creces tu cabello, te estás mutando a ti mismo: sigues siendo tú, pero uno de tus atributos es diferente.

En el caso de los primitivos, todos sus atributos están completamente determinados por su identidad; 1 siempre significa 1 , no importa qué, y 1 + 1 es siempre 2 . No puedes cambiar eso.

Si una variable int dada tiene el valor 1 , puede cambiarla para tener el valor 2 lugar, pero eso es un cambio total de identidad: ya no tiene el mismo valor que tenía antes. Eso es como cambiarme para señalar a otra persona en lugar de a mí: en realidad no me cambia, simplemente me cambia a me .

Con objetos, por supuesto, a menudo puede hacer ambas cosas:

StringBuilder sb = new StringBuilder("foo"); sb.append("bar"); // mutate the object identified by sb sb = new StringBuilder(); // change sb to identify a different object sb = null; // change sb not to identify any object at all

En lenguaje común, ambos se describirán como "cambio de sb ", porque las personas usarán " sb " para referirse a la variable (que contiene una referencia) y al objeto al que hace referencia (cuando se refiere a uno). Este tipo de relajación está bien, siempre y cuando recuerdes la distinción cuando importa.


Esta no es una respuesta completa, pero es una forma de probar la inmutabilidad de los valores de tipo primitivo.

Si los valores primitivos (literales) son mutables, entonces el siguiente código funcionaría bien:

int i = 10; // assigned i the literal value of 10 5 = i; // reassign the value of 5 to equal 10 System.out.println(5); // prints 10

Por supuesto, esto no es verdad.

Los valores enteros, como 5, 10 y 11 ya están almacenados en la memoria. Cuando establece una variable igual a uno de ellos, cambia el valor en la ranura de memoria donde i .

Puedes ver esto aquí a través del bytecode para el siguiente código:

public void test(){ int i = 10; i = 11; i = 10; }

Bytecode:

// access flags 0x1 public test()V L0 LINENUMBER 26 L0 BIPUSH 10 // retrieve literal value 10 ISTORE 1 // store it in value at stack 1: i L1 LINENUMBER 27 L1 BIPUSH 11 // same, but for literal value 11 ISTORE 1 L2 LINENUMBER 28 L2 BIPUSH 10 // repeat of first set. Still references the same literal 10. ISTORE 1 L3 LINENUMBER 29 L3 RETURN L4 LOCALVARIABLE this LTest; L0 L4 0 LOCALVARIABLE i I L1 L4 1 MAXSTACK = 1 MAXLOCALS = 2

Como puede ver en el bytecode (con suerte), hace referencia al valor literal (ejemplo: 10) y luego lo almacena en la ranura para la variable i . Cuando cambia el valor de i , solo está cambiando qué valor se almacena en esa ranura. Los valores en sí mismos no están cambiando, la ubicación de ellos es.


Los literales primitivos y las variables primitivas final son inmutables. No las variables primitivas final son mutables.

La identidad de cualquier variable primitiva es el nombre de esa variable y es obvio que dicha identidad es inmutable.


Sí, son inmutables. Son totalmente inalterables.

Hay una buena explicación enterrada here . Es para Go, pero es lo mismo en Java. O cualquier otro idioma en la familia C.


Immutable significa que cada vez que el valor de y el objeto ha cambiado, se crea una nueva referencia para él en la pila. No se puede hablar de inmutabilidad en el caso de tipos primitivos, solo las Clases de Contenedor son inmutables. Java usa copy_by_value no por referencia.

No importa si pasa variables primitivas o de referencia, siempre está pasando una copia de los bits en la variable. Entonces, para una variable primitiva, está pasando una copia de los bits que representan el valor y si está pasando una variable de referencia de objeto, está pasando una copia de los bits que representan la referencia a un objeto.

Por ejemplo, si pasa una variable int con el valor de 3, está pasando una copia de los bits que representan 3.

Una vez que se ha declarado una primitiva, its primitive type can never change , aunque su valor puede cambiar.