![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Alone |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: 3 Всего: 6 |
Так как в яве все объекты передаются по ссылке, то подскажите, как с этим правильно работать?
Как правильно использовать clone()? etc... -------------------- |
|||
|
||||
| Sun |
|
|||
|
Account removed ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1611 Регистрация: 14.8.2002 Репутация: 8 Всего: 48 |
На самом деле утверждение что в Java объекты передаются по ссылке не совсем верно, во всяком случае ссылка в Java это не тоже самое что ссылка в C++. Можно провести простой эксперимент подтверждающий это
В этом примере вместо "Test" будет выведено "blah-blah", тогда как в подобном коде на C++ с использованием ссылок будет выведено слово "Test". Похоже что при передаче объекта в метод происходит его клонирование. -------------------- Account removed |
|||
|
||||
| AntonSaburov |
|
|||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: 51 Всего: 118 |
Правильно работать - это значит знать и помнить, что все изменения, которые ты сделаешь будут относится к переданному объекту. Больше тут особо советовать нечего.
А по поводу clone() : Есть Cloneable специальный интерфейс, который дол;ен быть реализован если хочется создавать копию объекта. Если класс реализует Cloneable, то это говорит о том, что при вызове clone() будет создана копия обекта. Обычное присвоение для объекта оператором присваивания (=) фактически является перенаправлением ссылки, а не копированием полей из одного объекта в другой. Лучше всего почитать прямо в Java API об интерфейсе Cloneable и методе Object.clone(). |
|||
|
||||
| Sun |
|
|||
|
Account removed ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1611 Регистрация: 14.8.2002 Репутация: 8 Всего: 48 |
Вот нашел небольшую статью, утверждающую что "ВСЕ ПАРАМЕТРЫ В JAVA ПЕРЕДАЮТСЯ ПО ЗНАЧЕНИЮ".
http://www.javable.com/columns/robinson/letters/01/ Думаю с автором можно согласиться, правда не стоит говорить такого при тестировании или устройстве на работу -------------------- Account removed |
|||
|
||||
| Alone |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: 3 Всего: 6 |
Спасибо обоим
-------------------- |
|||
|
||||
| AntonSaburov |
|
||||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: 51 Всего: 118 |
В данном случае происходит создание нового объекта типа String и ссылка переданная в качестве параметра теперь указывает просто на новый объект. Тут важно отметить, что передаваемая ссылка и ссылка как аргумент - это разные ссылки. Т.е происходит копирование ссылки. Можно посмотреть на такой код:
Здесь интересен момент когда в ShowMe переменной mc присваивается указатель на новый объект. Т.е. теперь mc указывает уже на совсем другую переменную. И здесь тогда сразу видно, что переменная my2 в main и переменная mc как аргумент ShowMe - это две разные переменные-ссылки. Просто в первый момент вызова ShowMe они обе указывают на один и тот же объект. Вот и получаем эффект, который показан в примере Sun |
||||
|
|||||
| Alone |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: 3 Всего: 6 |
Я столкнулся с таким вот :
Создаю новый объект моего типа. myClass myObj=(myClass)myArray.get(n); По идее - объект новый, но изменив в нем значения полей, они изменятся и в myArray[n] То есть копирования не происходит, в myObj передается ссылка на объект из myArray[n] Это сообщение отредактировал(а) Alone - 16.12.2003, 18:12 -------------------- |
|||
|
||||
| daniel (yerevan| javaxp@ya |
|
|||
|
Unregistered |
yourClass ob1=new yourClass();
yourClas ob2; ob2=ob1; //ssylka na pamyat ob1 // ob1=null // ob2 sushestvuet |
|||
|
||||
| Alone |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: 3 Всего: 6 |
Дело в том, что в данной реализации моего кода я не передаю объект в качестве параметра.
Он у меня объявлен паблик. Может это и некорректно, но мне так проще к нему обращаться. Поэтому, для работы с ним, мне надо его скопировать(клонировать) для обеспечения возможности отмены изменений объекта. -------------------- |
|||
|
||||
| AntonSaburov |
|
||||||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: 51 Всего: 118 |
Так ты его не создаешь. Ты создаешь еще одну ссылку указывающую на один и тот же объект. А для создания копии надо честно скопировать все поля из одного объекта в другой. Т.е. если имеем объект
то копирование объекта в другой будет подобно
Причем стоит отметить следующее - если объект внутри себя имеет сылки на объекты (поле типа Object и все, что дальше по наследованию), то опять же простое присваивание таких полей сделает следующее: ссылки во втором объекте будут указывать на тот же объект, что и в первом. |
||||||
|
|||||||
| Alone |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: 3 Всего: 6 |
И всётаки... Что в этом случае лучше/корректней/проще/вернее сделать?
1. реализовать cloneable? 2. копировать ручками ( а если структура >20полей?, да и код увеличивается...) -------------------- |
|||
|
||||
| Alone |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: 3 Всего: 6 |
Вот, добрался до реализации Cloneable...
В связи с этим возникли вопросы: Для решения проблемы клонирования, объект должен реализовать метод clone() Делаем...
Идем дальше:
И наконец в главном коде:
-------------------- |
||||||
|
|||||||
| AntonSaburov |
|
|||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: 51 Всего: 118 |
Надо копировать список - и ручками. Т.е. создать новый список и скопировать туда содержимое из оригинала. Иначе никак не получится.
super.clone может копировать ТОЛЬКО primitive поля (int, double, long) |
|||
|
||||
| Alone |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: 3 Всего: 6 |
Хорошо, как тогда объяснить такое:
объект1
объект2
главный класс
результат выполнения: [root@alone java_tests]# java test pRow.eList[0].id=1 pRow.eList[1].s=s2 Create copy of pRow and change it pRow2.eList[0].id=22 pRow2.eList[1].s=s22 check original pRow.eList[0].id=1 pRow.eList[1].s=s2 Получилась "правильная" копия листа... не ссылки, а новые объекты! О, как! -------------------- |
||||||
|
|||||||
| Alone |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: 3 Всего: 6 |
Извиняюсь, ошибочка вышла... (с)Охота
вот здесь
а надо вот так:
и результат плачевный [root@alone java_tests]# java test pRow.eList[0].id=1 pRow.eList[1].s=s2 Create copy of pRow and change it pRow2.eList[0].id=22 pRow2.eList[1].s=s22 check original pRow.eList[0].id=22 pRow.eList[1].s=s2 -------------------- |
||||
|
|||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |