2009-12-24 18 views
12

He leído que en Java un objeto de tipo String no puede cambiar. Pero las variables int y char pueden. ¿Por qué es? ¿Puedes darme un ejemplo?La cadena no puede cambiar. Pero int, char puede cambiar

Gracias. (Yo soy un nuevo -_-)

+2

¿A qué te refieres con que no puedes cambiar? ¿Qué tal si nos das un ejemplo de lo que describes? – user151841

+2

Bienvenido a SO. Creo que necesitarás ser un poco más descriptivo para obtener una respuesta constructiva. :) –

+9

no entiendo por qué este tipo recibe un voto negativo. él es un novato y simplemente hace una pregunta. al dar un voto negativo lo desanima. y no puedo ver qué está mal con la pregunta, ¡es válida! –

Respuesta

18

Como dijo bzabhi, las cadenas son inmutables en Java. Esto significa que un objeto de cadena nunca cambiará. Esto no significa que no pueda cambiar las variables de cadena, solo que no puede cambiar la representación de memoria subyacente de la cadena. para un ejemplo:

String str = "Hello"; 
str += " World!"; 

Después de la ejecución de estas líneas, str apuntará a una nueva cadena en la memoria. La cadena original "Hola" aún existe en la memoria, pero lo más probable es que no esté allí por mucho tiempo. Suponiendo que no haya circunstancias atenuantes, nada estará apuntando a la cadena original, por lo que será basura recolectada.

Supongo que la mejor manera de decir esto sería decir que cuando se ejecuta la línea 2 del ejemplo, se crea una nueva cadena en la memoria a partir de la concatenación de la cadena original y la cadena que se le agrega. La variable str, que es solo una referencia a una ubicación de memoria, se cambia para apuntar a la nueva variable que se acaba de crear.

No estoy particularmente bien informado sobre el punto, pero, según tengo entendido, esto es lo que sucede con todos los valores "no primitivos". Todo lo que en algún punto deriva de Object sigue estas reglas. Los valores primitivos, como ints, bools, chars, floats y dobles permiten cambiar el valor real en la memoria. Por lo tanto, a partir de esto:

int num = 5; 
num += 2; 

cambia el valor real en la memoria. En lugar de crear un objeto nuevo y cambiar la referencia, este ejemplo de código simplemente cambiará el valor en la memoria para la variable num.

En cuanto a por qué esto es cierto, es simplemente una decisión de diseño por los creadores de Java. Estoy seguro de que alguien comentará por qué se hizo esto, pero eso no es algo que yo sepa.

+0

* ¿Por qué? * Solo estoy adivinando aquí, pero probablemente sea porque si extendieras una cadena tendrías que volver a asignar memoria de todos modos. Los caracteres se almacenan contiguamente y es posible que el siguiente carácter no esté disponible para su uso, por lo que solo reasigna un nuevo fragmento de memoria en ambos sentidos. – mpen

+0

es decir, es más eficiente de esta manera (en la mayoría de los casos). A menos que quiera asignar enormes cadenas solo para uso potencial. Pero eso es lo que StringBuffer es para ... – mpen

+0

(compararía 'int' con' Integer' - se comportan de manera similar. 'AtomicInteger' y' StringBuilder', por ejemplo, se comportan de forma bastante diferente de 'Integer' /' int' y 'String'.) –

9

int y el carácter no puede cambiar tampoco. Al igual que con las cadenas, puede poner un valor diferente en la misma variable, pero un entero en sí mismo no cambia. 3 siempre será 3; no puede modificarlo para que sea 4.

3

No estoy seguro de que sea posible mostrar (por ejemplo) que las cadenas no pueden cambiar. Pero puede confirmarlo leyendo la sección de descripción de Javadoc for the String class, luego leyendo la sección de métodos y observando que no hay métodos que puedan cambiar una cadena.

EDIT: Hay muchas razones por las que las cadenas están diseñadas para ser inmutables en Java. La razón más importante es que las cadenas inmutables son más fáciles de usar que las mutables. Y si necesita el equivalente mutable de una Cadena por alguna razón, puede usar la clase StringBuilder (o StringBuffer).

4

cadena es un tipo inmutable (el valor dentro de ella no se puede cambiar). Lo mismo es cierto para todos los tipos primitivos (booleano, byte, char, corto, int, largo, flotante y doble).

int x; 
String s; 

x = 1; 
x = 2; 
s = "hello"; 
s = "world"; 
x++; // x = x + 1; 
x--; // x = x - 1; 

Como se puede ver, en ningún caso puede alterar el valor constante (1, 2, "hola", "mundo"), pero se puede modificar en el que están apuntando (si deformar un poco la mente y decir que una variable int apunta a un valor int constante).

2

También vale la pena tener en cuenta que las cadenas son inmutables, que si se pasan a un método, no se pueden modificar dentro del método y luego se ven esos cambios fuera del alcance del método.

public void changeIt(String s) { 
    // I can't do anything to s here that changes the value 
    // original string object passed into this method 
} 

public void changeIt(SomeObject o) { 
    // if SomeObject is mutable, I can do things to it that will 
    // be visible outside of this method call 
} 
1

Las cadenas son inmutables en java. Sin embargo, aún puede agregar o anteponer valores a cadenas. Por valores, me refiero a tipos de datos primitivos u otras cadenas.

Sin embargo, un StringBuffer es mutable, es decir, se puede cambiar en la memoria (no es necesario asignar un nuevo bloque de memoria), lo que lo hace bastante eficiente. También, considere el siguiente ejemplo:

StringBuffer mystringbuffer = new StringBuffer(5000); 

for (int i = 0; i<=1000; i++) 
{ 
    mystringbuffer.append ('Number ' + i + '\n'); 
} 

System.out.print (mystringbuffer); 

En lugar de crear un mil cuerdas, creamos un único objeto (mystringbuffer), que puede expandirse en longitud. También podemos establecer un tamaño de inicio recomendado (en este caso, 5000 bytes), lo que significa que el búfer no tiene que estar solicitando memoria continuamente cuando se le agrega una nueva cadena.

Mientras que StringBuffer no mejorará la eficiencia en cada situación, si su aplicación usa cadenas que crecen en longitud, sería eficiente. El código también puede ser más claro con StringBuffer s, porque el método de adición le ahorra tener que usar declaraciones de asignación larga.

Cuestiones relacionadas