Страницы

Поиск по вопросам

вторник, 28 января 2020 г.

Java. Почему нельзя изменить ссылку на объект в методе?

#java #ссылки #объекты #теория #параметры


Мой педагог задал мне задание ответить на ряд вопросов. И два их них меня сильно
смущают. 


  
  Почему нельзя изменить ссылку на объект в методе?
  


Не могу понять смысл вопроса(((


  
  Как в Java передаются параметры в методы?
  


Я гуглил этот вопрос и понял что по всегда по значению но что точно это значит не понял.

Не могли бы вы мне помочь разобраться в этой ситуации.
    


Ответы

Ответ 1



Почему нельзя изменить ссылку на объект в методе? Потому что в метод передается не ссылка, а объект, который содержит копию ссылки. Как в Java передаются параметры в методы? Все аргументы (как примитивные типы, так и объекты) в Java передаются при вызове по значению. Тут сразу стоит оговориться, что объект по сути представляет ссылку, следовательно, при изменении объекта в методе, изменится и исходный объект. Подробнее можно почитать в «Подробное рассмотрение особенностей передачи аргументов» в полном руководстве по Java авторства Герберта Шилдта.

Ответ 2



Как намекнул Vlad from Moscow в комментарии к вопросу, вопрос довольно странный, и на мой взгляд он не вполне корректен -- либо ваш преподаватель не очень хорошо умеет выражать свои мысли, либо вы как-то слегка исказили его вопрос. Дело в том, что в методе менять ссылку вообще-то можно. Строго говоря, в Jave обычно говорят не о ссылках на объект, а о переменных (полях, аргументах) объектного типа. Но фактически значением таких переменных являются ссылки на объекты. Методы в качестве своих аргументов получают копии этих ссылок и могут делать с ними что хотят (т. е. присваивать им значения ссылок на другие объекты или null - "пустую ссылку"), что никак не отражается на значениях переменных, которые были переданы методу при его вызове. Так что вот такой код public class TestQQ { static void qq(String s) { System.out.println(s); s = "Что-то новое..."; // Это ссылка или не ссылка меняется ? System.out.println(s); } public static void main(String[] args) { String string = "Нельзя менять ссылки?"; qq(string); System.out.println(string); } } Создает новый объект класса String со значением "Нельзя менять ссылки?"; Присваивает ссылку на него переменной string; Вызывает метод qq() и передает ему копию переменной string (т. е. создает вторую ссылку на ту же строку "Нельзя менять ссылки?") Метод qq() выводит на консоль содержимое того объекта, ссылка на который содержится в его параметре - т. е. то же самое "нельзя?"; Метод qq() своему параметру s присваивает новое значение - ссылку на новую строку "Что-то новое...", -- вторая ссылка на "нельзя" исчезает, но исходная переменная string в главной программе при этом никак не меняется и по-прежнему содержит ссылку на то же самое изначальное "нельзя?"; Метод qq() печатает новую строку ("Что-то новое...") и возвращает управление в главную программу (метод main); Метод main() печатает содержимое объекта, который содержится (т. е. ссылка на который содержится) в переменной string - это по-прежнему изначальная строка "Нельзя менять ссылки?" Вывод будет такой:Нельзя менять ссылки? Что-то новое Нельзя менять ссылки? Но при этом надо отчетливо понимать, что хотя метод не может изменить значение объектной переменной, переданной ему в качестве параметра (т. е. ссылку на объект), он за милую душу может изменить сам объект! Например, в такой программе import java.util.ArrayList; public class TestQQQ { static void qqq(ArrayList list) { list.add("можно."); } public static void main(String[] args) { ArrayList strings = new ArrayList(); strings.add("А объекты менять...?"); qqq(strings); System.out.println(strings); } } метод qqq() добавляет в список, ссылку на который он получил, новую строку "можно.", и в результате мы получаем на выходе вот что: [А объекты менять...?, можно.]

Ответ 3



Почему нельзя изменить ссылку на объект в методе? При передаче объекта в метод происходит просто копирование ссылки на него (Никаких копий объекта не создаётся при передачи!). И уже с помощью неё вы общаетесь с исходным объектом. Отсюда должно быть понятно, почему при перезаписывании в эту ссылку нового объекта старый не меняется. Простой пример для разъяснения: List list1 = new ArrayList<>(); //Создаём объект и кладём в ссылку List list2 = list1; //Просто копируем ссылку list2.add(new Object); //Через копию ссылки мы меняем исходный объект в list1 list2 = new ArrayList<>(); //Хоть мы и переписали в ссылку новый объект, //исходный никуда не делся, он всё также лежит в list1. Как в Java передаются параметры в методы? Примитивы по значению, объекты - как я описал выше (не знаю как правильно называется этот способ). Update: спасибо @Roman, правильное название способа передачи объектов в метод - вызов по соиспользованию (call by sharing)

Комментариев нет:

Отправить комментарий