2012-06-13 22 views
16

Soy nuevo en Java y tengo algunas preguntas en mente con respecto a la asignación de objetos. Por ejemplo,Asignación de objetos Java

Test t1 = new Test(); 
Test t2 = t1; 
t1.i=1; 

Suponiendo variable de i se define dentro de la clase de prueba, estoy derecho de asumir tanto t1 y t2 punto al mismo objeto cuando la modificación afecta tanto t1.i=1t1 y t2? En realidad lo probé y parece que tenía razón. Sin embargo, cuando intento lo mismo en String, la modificación ocurre solo en un lado donde el otro lado no se ve afectado. Cuál es la razón detrás de esto?

Editar: El caso probé con String.

String s1 = "0"; 
String s2 = s1;   
s1 = "1"; 
System.out.println(s1); 
System.out.println(s2); 

que se dan cuenta de mi error al probar los casos en cadena ya que es inmutable. La situación en la que pensé s1="1" modificar la cadena es, de hecho, devolver la referencia de "1" a la s1. Sin embargo, mi pregunta permanece. ¿Hace Test t2 = t1; que tanto t2 como t1 apuntan al mismo objeto o cada uno tiene sus propios objetos? ¿Esta situación se aplica a todos los objetos en Java?

+0

¿Qué quiere decir con 'probar lo mismo en String'? No hay métodos en el objeto String para modificar la cadena en sí. Por favor, lea la documentación cuidadosamente. – DRCB

+0

Si publica el código de la prueba que está haciendo en String, podemos ser más específicos sobre lo que está haciendo incorrectamente –

Respuesta

14

Tiene razón, pero las cuerdas son un caso especial; son inmutables y actúan como primitivos en este caso.

@newacct

cito http://docs.oracle.com/javase/tutorial/java/data/strings.html:

Nota: La clase String es inmutable, por lo que una vez que se crea un objeto cadena no se puede cambiar. La clase String tiene un número de métodos, algunos de los cuales se analizarán a continuación, que parecen modificar cadenas. Dado que las cadenas son inmutables, lo que realmente hacen estos métodos es crear y devolver una nueva cadena que contenga el resultado de la operación .

Esto es lo que hace que las cuerdas sean un caso especial. Si no sabe esto, puede esperar que los métodos discutidos en la cita no devuelvan cadenas nuevas, lo que llevaría a resultados inesperados.

@ user1238193

Teniendo en cuenta su siguiente pregunta: "¿Se t2 Prueba = t1; causar tanto t2 y el instante t1 al mismo objeto o cada ahora tienen sus propios objetos ¿Esta situación se aplica en todos los objetos de Java? "

t1 y t2 apuntarán al mismo objeto. Esto es cierto para cualquier objeto java (objetos inmutables incluidos)

+2

No hay" casos especiales ". La asignación a una referencia de cualquier tipo cambia el objeto al que apunta, sin afectar el objeto al que apuntaba. – newacct

+0

Las cadenas son un caso especial; son objetos, pero son inmutables, lo que significa que si intentas cambiarlos por ejemplo String.replace, obtendrás un objeto nuevo en lugar de un mismo objeto mutado. – Tom

+2

No, 'String' simplemente no tiene ningún método que lo modifique. "intenta cambiarlos" no tiene sentido; no puedes "intentar" hacer algo que no existe. 'String.replace' te da un nuevo objeto: ¿cuál es tu punto? Eso es lo que su documentación dice que hará. 'Integer' y muchas otras clases son inmutables. Puede escribir trivialmente una clase que sea inmutable, haciendo que los campos sean privados y sin proporcionar ningún método para cambiar sus campos. Y en cualquier caso, la mutabilidad es irrelevante para la pregunta, que originalmente era sobre cambiar un campo en 'Test', pero no hay campos públicos en' String' – newacct

3

Tiene toda la razón, ya que tanto t1 como t2 se refieren al mismo objeto, cualquier chane en el estado del objeto afectará a ambos.

La cadena es un objeto inmutable. Entonces no puede ser modificado en absoluto. see this para obtener más información sobre objetos inmutables en java.

+0

http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html –

+0

Eso no explica el problema. Lo mismo ocurre con 'Test':' Test s1 = new Test (2); Prueba s2 = s1; s1 = new Test (1); ' – newacct

2

String objects are immutable.


EDITAR

¿Tiene Test t2 = t1; causa tanto t2 y el instante t1 al mismo objeto o cada ahora tienen sus propios objetos?

Sí. Aunque t2 es una referencia nueva, pero apuntará al mismo objeto, porque usted le dijo que lo hiciera. Cree una nueva referencia t2 de tipo Test y permítale señalar el mismo objeto al que apunta t1.

Pero, cuando haces esto con String sy luego haces algo como s1 = "1" ; estás haciendo s1 apunta a otro objeto String. Puedes pensarlo en los términos s1 = new String(1);.

+0

Eso no explica el problema. Lo mismo ocurre con 'Test':' Test s1 = new Test (2); Prueba s2 = s1; s1 = new Test (1); ' – newacct

+0

@newacct El OP editó la publicación más tarde. La publicación inicial respondía solo con estas pocas palabras. Editaré mi publicación ahora. Gracias por señalarlo. –

+0

Incluso antes de la edición, "Cadena es inmutable" no es la respuesta correcta. Él dijo "cuando probé lo mismo en String"; la respuesta debería ser "Lo que dijiste es imposible. Es imposible hacer lo mismo con String" – newacct

1

Las cuerdas son objeto como cualquier otro. Entonces, cualquier variable que les asigne se refiere a la misma instancia del objeto, como lo hace con su objeto de prueba.

Pero tenga en cuenta que String no tiene ningún campo que pueda establecer como lo hace en Prueba, por lo que básicamente no puede hacer la misma prueba, por lo que no hay forma de transferir el código del objeto Prueba al objeto Cadena.

Usted obtiene un comportamiento opuesto utilizando los tipos primitivos, como mucho, int etc. que están asignados a las variables "por valor", por lo que si lo hace

int t1 = 12; 
int t2 = t1; 
t1=15; 

t2 todavía tiene valor de 12

5

Usted están en lo correcto con su primera suposición. Con la siguiente línea de código:

Test t1 = new Test(); 

se crea un nuevo objeto de prueba, y en el mismo tiempo se crea una referencia de prueba denominado T1 para referirse a ella.

En la segunda línea del código que envió:

Test t2 = t1; 

va a crear en realidad otra referencia de prueba, y lo ha asignado a refieren al mismo objeto que se refiere a t1.

Entonces t1.i = 1; afectará a t2.i porque es el mismo objeto después de todo.

En cuanto a las cadenas, las cadenas son inmutables y no se pueden modificar una vez creadas.

Con respecto a su edición:

String s1 = "0"; 
String s2 = s1;   
s1 = "1"; 
System.out.println(s1); 
System.out.println(s2); 

Se imprimirán diferentes resultados, porque cuando en realidad se dice

s1 = "1"; 

en realidad se está atando s1 a otro objeto String, pero s2 seguirán refiriéndose a el objeto con el valor "0".

2

Usted está haciendo cosas completamente diferentes en los dos casos. En el primer caso, con t1.i = 1;, está modificando el objeto apuntado por t1.En el segundo caso, la t1 = "1";, va a cambiar la referencia al punto a otro objeto (similar a cuando se hizo t2 = t1;.

Si lo hace lo mismo a Test que lo hizo en el segundo caso, se llega a la mismo resultado (asumiendo Test tiene un constructor que toma un entero):.

Test t1 = new Test(5); 
Test t2 = t1;   
t2 = new Test(1); // Here we are assigning to the variable, just like your 2nd example 
System.out.println(t1); 
System.out.println(t2); 

personas mencionan que String es inmutable Pero eso es irrelevante y no existe el concepto de "mutabilidad" en la lengua y no hay diferencia entre las clases "mutables" e "inmutables" funcionan. Informamos informalmente que una clase es "inmutable" si no tiene ningún campo ds puede configurar o cualquier método que pueda cambiar su contenido interno. Tal es el caso con String. Pero una clase mutable funcionaría exactamente de la misma manera si simplemente no haces nada para mutarla.

+0

Antes de declinar y comentar otras respuestas, por favor amablemente no te molestes en ver el historial de edición de preguntas. Eso le dará una pista de por qué muchas respuestas, diciendo lo mismo, se votaron en sentido ascendente. –

Cuestiones relacionadas