2012-06-13 4 views
16

Я новичок в Java, и у меня есть некоторые вопросы в отношении назначения объектов. Например,Назначение объектов Java

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

Предполагая, что переменная i определяется внутри класса Test, я вправе предположить, как t1 и t2 точку на тот же объект, где модификация t1.i=1 влияет как t1 и t2? На самом деле я проверил это и, похоже, был прав. Однако, когда я пытаюсь сделать то же самое на String, модификация происходит только с одной стороны, где другая сторона не подвержена влиянию. В чем причина этого?

Редактировать: Случай, который я пробовал со строкой.

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

Я реализую свою ошибку, проверяя случаи на String, поскольку он является неизменным. Ситуация, когда я думал, что изменение строки на самом деле возвращает ссылку «1» на s1. Тем не менее, мой вопрос остается. Test t2 = t1; приводит к тому, что t2 и t1 указывают на один и тот же объект или у каждого теперь есть свои собственные объекты? Используется ли эта ситуация для всех объектов на Java?

+0

Что вы подразумеваете под «попробовать то же самое на String»? В объекте String нет методов для изменения самой строки. Пожалуйста, внимательно прочитайте документацию. – DRCB

+0

Если вы публикуете код теста, который вы делаете на String, мы можем быть более конкретным в отношении того, что вы делаете неправильно. –

ответ

14

Вы правы, но Струны - это особый случай; они неизменны и действуют как примитивы в этом случае.

@newacct

цитирует http://docs.oracle.com/javase/tutorial/java/data/strings.html:

Примечания: Класс Строки неизменен, так что, как только он будет создан объект Строки не может быть изменен. Класс String имеет число методов, некоторые из которых будут рассмотрены ниже, которые отображаются в , чтобы изменить строки. Поскольку строки неизменяемы, то эти методы действительно do создают и возвращают новую строку, которая содержит результат операции .

Это то, что делает струны особым случаем. Если вы этого не знаете, вы можете ожидать, что методы, обсуждаемые в цитате, не возвращают новые строки, что приведет к неожиданным результатам.

@ user1238193

Учитывая ваш следующий вопрос: «Есть ли тест t2 = t1, вызывать как t2 и точку t1 и тот же объект или каждый из них сейчас имеет свои собственные объекты ли применяет эту ситуацию на все объекты на Java? "

t1 и t2 указывают на один и тот же объект. Это справедливо для любого объекта java (включая неизменяемые объекты)

+2

Нет« особых случаев ». Присвоение ссылки любого типа изменяет объект, на который он указывает, без влияния на объект, на который он указывал. – newacct

+0

Струны - это особый случай; они являются объектами, но они неизменяемы, что означает, что если вы попытаетесь изменить их, например, String.replace, вы получите новый объект вместо того же самого мутированного объекта. – Tom

+2

Нет, 'String' просто не имеет никакого метода, который его изменяет. «попытаться изменить их» не имеет смысла; вы не можете «попытаться» сделать что-то, чего не существует. 'String.replace' дает вам новый объект - в чем ваш смысл? Вот что говорит его документация. 'Integer' и многие другие классы неизменяемы. Вы можете тривиально написать класс, который является неизменным, делая частные поля и не предоставляя методов для изменения его полей. И в любом случае, изменчивость не имеет отношения к вопросу, который первоначально касался изменения поля в 'Test', но нет никаких открытых полей в' String' – newacct

3

Вы абсолютно правы, так как оба t1 и t2 ссылаются на один и тот же объект, любое состояние в объекте влияет на оба.

String - неизменный объект. Поэтому он не может быть изменен вообще. see this для получения дополнительной информации о неизменяемом объекте в java.

+0

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

+0

Это не объясняет проблему. То же самое относится к 'Test':' Test s1 = new Test (2); Тест s2 = s1; s1 = новый тест (1); ' – newacct

2

String objects are immutable.


EDIT

ли Test t2 = t1; причиной как t2 и t1 точка на тот же объект или каждый из них сейчас имеют свои собственные объекты?

Да. Хотя t2 - это новая ссылка, но она укажет на тот же объект, потому что вы сказали это сделать. Создайте новую ссылку t2 типа Test и дайте ей указать на тот же объект, на который указывает t1.

Но, когда вы делаете это с помощью String и затем делаете что-то вроде s1 = "1" ;, вы делаете s1 на другом объекте String. Вы можете подумать об этом в терминах s1 = new String(1);.

+0

Это не объясняет проблему. То же самое относится к 'Test':' Test s1 = new Test (2); Тест s2 = s1; s1 = new Test (1); ' – newacct

+0

@newacct OP отредактировал сообщение позже. Первоначальная должность была ответственна только за эти несколько слов. Сейчас я отредактирую свой пост. Спасибо, что указали на это. –

+0

Даже до редактирования «Строка неизменна» не является правильным ответом. Он сказал: «Когда я пробовал то же самое на String»; ответ должен быть «То, что вы сказали, невозможно. Нельзя сделать то же самое для String» – newacct

1

Строка - объект, как любой другой. Таким образом, любая переменная, которую вы их назначаете, относится к тому же экземпляру объекта, как и к вашему тестовому объекту.

Но имейте в виду, что у String нет поля, которое вы можете установить так же, как в Test, поэтому вы в принципе не можете выполнить один и тот же тест, поэтому нет способа перенести свой код из объекта Test в объект String.

Вы противоположное поведение, используя примитивные типы, такие длинные, внутр и т.д. Они присваиваются переменным «по значению», так что если вы

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

t2 все еще имеет значение 12

5

Вы правы с вашего первого предположения. С помощью следующей строки кода:

Test t1 = new Test(); 

создать новый объект испытаний, и в то же время вы создаете ссылку Test именем t1 сослаться на него.

На второй строке кода вы вывесили:

Test t2 = t1; 

Вы фактически создаете другую ссылку теста, и вы назначаете его ссылаться на тот же объект, что t1 относится.

Так что t1.i = 1; повлияет на t2.i, потому что это тот же самый объект.

Что касается строк, строки являются неизменяемыми и не могут быть изменены после создания экземпляра.

Что касается вашего редактирования:

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

Они будут печатать различные результаты, потому что, когда вы на самом деле сказать

s1 = "1"; 

вы на самом деле связывание s1 к другому объекту Струнного, но s2 будет по-прежнему ссылаются на объект со значением «0».

2

Вы делаете совершенно разные вещи в двух случаях. В первом случае, с t1.i = 1;, вы изменяете объект, на который указывает t1.Во втором случае, с t1 = "1";, вы меняете ссылку, чтобы указать на другой объект (подобно тому, когда вы сделали t2 = t1;.

Если вы делаете то же самое с Test, что вы сделали во втором случае вы получите Такой же результат (при условии Test имеет конструктор, который принимает целое число):.

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); 

Люди упоминают, что String неизменна Но это не имеет никакого отношения, и нет никакого понятия «изменяемости» в языке, и нет никакой разницы между как работают «изменчивые» и «неизменные» классы. Мы неофициально заявляем, что класс «непреложный», если он не имеет какого-либо фила ds вы можете установить или любые методы, которые могут изменить его внутренний контент. Так обстоит дело с String. Но изменчивый класс будет работать точно так же, если вы просто не сделаете ничего, чтобы его мутировать.

+0

Перед тем, как опробовать и прокомментировать другие ответы, пожалуйста, не стесняйтесь просматривать историю изменений вопроса. Это даст вам подсказку, почему многие ответы, говорящие одно и то же, были поддержаны. –

Смежные вопросы