Назначение объектов Java - программирование
Подтвердить что ты не робот

Назначение объектов Java

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

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

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

Изменить: случай, который я попробовал с помощью String.

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

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

4b9b3361

Ответ 1

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

@newacct

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

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

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

@user1238193

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

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

Ответ 2

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

Test t1 = new 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 к другому объекту String, но s2 все равно будет ссылаться на объект со значением "0".

Ответ 3

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

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

Ответ 4

Объекты String неизменяемы.


ИЗМЕНИТЬ

Указывает ли Test t2 = t1;, что t2 и t1 указывают на один и тот же объект, или у каждого теперь есть свои собственные объекты?

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

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

Ответ 5

В двух случаях вы делаете совершенно разные вещи. В первом случае с 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 является неизменным. Но это не имеет значения, и в языке нет понятия "изменчивости", и нет никакой разницы между тем, как работают "изменяемые" и "неизменные" классы. Мы неформально заявляем, что класс является "неизменным", если у него нет каких-либо полей, которые вы можете установить, или любых методов, которые могут изменить его внутренний контент. Так обстоит дело с String. Но изменяемый класс будет работать точно так же, если вы просто не сделаете ничего, чтобы его мутировать.

Ответ 6

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

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

Вы получаете противоположное поведение с использованием примитивных типов, таких как long, int и т.д. Они присваиваются переменным "по значению", поэтому, если вы делаете

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

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