0 / 0 / 0
Регистрация: 01.06.2011
Сообщений: 18
1

Как добиться неизменности параметра метода при его вызове?

01.06.2011, 14:59. Показов 1661. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Хочу чтобы параметр метода не менялся внутри него. Пишу так

Java
1
2
3
void someFunction(final SomeObject someObject){
  someObject = null;
}
и это не проходит.

А если в классе SomeObject есть Sett'er метод для некоторого поля - field, то возможно следующее:

Java
1
2
3
void someFunction(final SomeObject someObject){
  someObject.setField(newField);
}
и это проходит.

Как добиться того, чтобы обьект не менялся???
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.06.2011, 14:59
Ответы с готовыми решениями:

Ошибка при вызове метода
добрый вечер. Сделал задание в Си# теперь его надо перевести в Java. Вот привожу отрывок кода как...

NulPointerlException при вызове метода другого класса
При нажатии на кнопку в "New" (фрейм) должен выполняться метод catchNew класса Panel, наследника...

JNA и WinSock ошибка при вызове метода
пытаюсь реализовать при помощь JNA и WinSock. Пишу интерфейс private interface Winsock extends...

Исключение ClassNotFoundException при при вызове метода Class.forName
Сразу говорю опыта у меня мало )) Разработанный в Oracle9i JDeveloper проект был перенесен на...

13
mishgun
01.06.2011, 20:44 2
Bred kakoy to.
Metody i sushestvuyut chtob izmenyat kakie-to dannie.
Ne hotitte chtob value menyalos obyavite

final Sting STR_CONSTANT ='dont'change';
1 / 1 / 0
Регистрация: 15.02.2010
Сообщений: 311
01.06.2011, 23:01 3
Передайте клон в качестве параметра. При этом оригинал, естественно, останется в неприкосновенности.

Однако зачем такие сложности?... Вы что, не знаете, что Вы делаете?
0
bid_relib
02.06.2011, 00:01 4
да уж - вопрос задавался, наверное, в состоянии глубокого раздумья или отдладки-)
и ответы прикольные-))
0 / 0 / 0
Регистрация: 01.06.2011
Сообщений: 18
02.06.2011, 08:04  [ТС] 5
Почему спецификатор final отвечает только за ссылку на сам обьект,
и не распростроняется на его содержимое - по-моему это не очень логично. И зачем тогда он вообще нужен в таком описании функции:
Java
1
void someFunction(final SomeObj someObj){}
0
1 / 1 / 2
Регистрация: 07.01.2010
Сообщений: 128
02.06.2011, 12:23 6
Из вопроса не ясно, 'Хочу чтобы параметр метода не менялся внутри него' - это просто бунт разума против реальности, или планируется что-то типа Template Method или Injection of Control?

Если верно второе, то можно сказать следующее:
1. Мне не видится осмысленным в контексте этого вопроса обсуждать, ПОЧЕМУ модификатор final для параметра работает так, а не иначе.
2. 'Правильное' решение состоит в следующем: допустим, у вас есть класс C, экземпляр которого нужно передать в метод. Сделайте рефакторинг так, чтобы появился интерфейс I, содержащий только accessor methods этого класса, а класс C реализовывал этот интерфейс и добавлял к нему mutator methods. Тогда в своем коде вы будете использовать переменные типа C для хранения своих объектов, а вовне эти же объекты передавать через параметры типа I.
Здесь есть один тонкий момент: если какой-либо accessor method возвращает Collection, то эту коллекцию, вероятнее всего, можно модифицировать, т.к. возврат копий коллекций или unmodifiable коллекций практикуется редко. Поэтому, в такой ситуации нужно решить, что есть меньшее зло: обернуть корневой объект во wrapper class, который будет перехватывать возвращаемые коллекции и оборачивать их в unmodifiable, или всегда возвращать unmodifiable Collection.
Еще лучше сделать два интерфейса: [только accessor methods] -> [+ mutator methods] -> [класс]
3. Есть извращенный путь: использовать dynamic proxy, который будет контролировать доступ к методам.
4. Есть еще один извращенный путь: копировать объект перед передачей в метод. В этом случае нужно позаботиться, чтобы копирование было 'deep', то есть если корневой объект ссылается еще на какие-то объекты, должны копироваться не эти ссылки, а сами объекты.
0
paradise
02.06.2011, 12:27 7
Код на 5 баллов.
Java
1
2
3
void someFunction(final SomeObject someObject){
 someObject.setField(newField);
}
>Почему спецификатор final отвечает только за ссылку на сам обьект,
>и не распростроняется на его содержимое - по-моему это не очень логично.

А по-моему, не очень логично пытаться запретить изменение объекта внутри отдельно взятого метода.

На секунду представим, что final распространяется на объект. Т.е. тебе надо заставить всех, кто будет писать методы, использующие этот объект писать final с сигнатуре. Как это сделать - не понимаю. Зачем - тоже вопрос?

Если ты пишешь метод, который не должен менять объект - просто не меняй его.

Передавать копию объекта (клонировать) правильный выход в случае если ты хочешь оставить в покое исходный объект.

Если не секрет, зачем тебе это? (Или, как принято спрашивать в некоторых формумах, где вы покупаете траву ?)
paradise
02.06.2011, 12:35 8
>Хочу чтобы параметр метода не менялся внутри него

Как раз это ты и получишь - параметр метода - сслыка, а не объект.
1 / 1 / 2
Регистрация: 07.01.2010
Сообщений: 128
02.06.2011, 13:26 9
Поправка для внимательных: в моем предыдущем посте вместо Injection of Control читать Inversion of Control
0
0 / 0 / 0
Регистрация: 01.06.2011
Сообщений: 18
02.06.2011, 17:07  [ТС] 10
Предоставляя пользователю некоторый класс, как я могу гарантировать
что вызываемые методы не искаверкают передаваемые в них обьекты этого
пользователя?? И как узнать меняет ли метод какого-то класса мой обьект??

По-моему это обычная задача обеспечения безопасности и она
не так уж бессмыслена.
0
1 / 1 / 2
Регистрация: 07.01.2010
Сообщений: 128
02.06.2011, 18:25 11
Если пользователь вызывает метод вашего класса и передает ему аргумент-объект, то он сам должен позаботиться, чтобы передаваемый объект был неизменяемым. В противном случае то никто не должен требовать от вашего кода гарантий, что аргумент не будет изменен.
Если речь идет об обратной ситуации, смотрите мои предыдущие сообщения.
0
1 / 1 / 3
Регистрация: 03.08.2008
Сообщений: 391
05.06.2011, 13:01 12
Думаю что вопрос решается клонированием.
Например:
Есть некий контекст SystemContext
в нём есть метод getMainCompany()

private static Company company;
....

public static Company getMainCompany() {
return (Company) company.clone();
}

И всё кто вычитывет объект компания может делать с ним что угодно
Если имя компании будет измененно....то вычитка методом
Company SystemContext.getMainCompany()
будет всё равно возвращать исходную компанию
0
1 / 1 / 3
Регистрация: 03.08.2008
Сообщений: 391
05.06.2011, 13:03 13
И ещё ..если поля объекта токо на чтение то в чём проблема....
создавай токо get методы....
а поля инить в конструкторе.....
0
0 / 0 / 0
Регистрация: 01.06.2011
Сообщений: 18
05.06.2011, 13:12  [ТС] 14
Спасибо всем!!!

Я поступил так:

В классе реализовал интерфейс: Readable,
который содержит только Get'er методы
моего обьекта (ну или все те, которые не изменяют обьект).
Теперь в качестве если параметра
передавать нге сам обьект а приводить его к
интерфейсу, то метод не сможет поправить обьект.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.06.2011, 13:12
Помогаю со студенческими работами здесь

JS: Как заменить свойство объекта при вызове его метода?
const Some = { hello: 'hello', sayHello: function() { console.log( this.hello ); }, ...

Как указывать аргументы при вызове одного метода из другого?
Добрый день! Прошу прощения за совсем примитивизм: public void panel1_paint(Object sender,...

Как узнать сколько было блокировок при вызове метода
привет есть многопоточное приложение использую synclock можно как то узнать как часто потоки...

Что означает первый параметр метода этого класса? И почему при вызове метода передаётся один параметр(второй)?
public static HelpPageApiModel GetHelpPageApiModel(this HttpConfiguration config, string...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru