2015-11-18 2 views
3

У меня есть метод, который принимает несколько аргументов, некоторые из этих аргументов будут изменены внутри метода. Некоторые из них используются только для чтения. Клиент (другие части кода, вызывающие такой метод) предоставляет экземпляры объектов в качестве аргументов.Конструкции языка Java, указывающие, что аргумент не будет мутирован?

Какие существуют конструкции языка Java, которые позволяют мне заявить, что аргумент не должен или не будет или не может быть мутирован внутри метода. Constrcuts как аннотации или ключевые слова, которые говорят клиенту, что метод не будет изменять экземпляры объектов, используемые в качестве аргументов в вызове метода. Также создаются конструкции, которые генерировали бы ошибки компиляции или предупреждение в случае, если я (как разработчик такого метода) попытаюсь случайно мутировать объект внутри реализации метода.

Я знаю о ключевом слове final, но это только для того, чтобы ссылка не обновлялась.

Неизменность - это не решение, как в других методах (или где-либо еще в моем приложении). Я хочу, чтобы экземпляры типа изменялись, только внутри этого вызова метода я хочу дать «обещание» клиенту , что я не буду изменять свой экземпляр, предоставленный в качестве аргумента.

Глубокое копирование или клонирование аргумента или разрешение клиенту (вызывающему) сделать такую ​​вещь не требуется, так как она не является частью логики метода, чтобы каким-либо образом изменить экземпляр. Я просто хочу узнать, поможет ли язык двойной проверки, этого не произойдет.

+0

Вы можете сделать глубокую копию и передать это. – John

+0

Один грязный способ - использовать [StackTraceElement] (http://stackoverflow.com/questions/421280/how-do-i-find-the-caller-of-a-method-using-stacktrace-or-reflection) для извлечения последнего вызываемого метода/класса. Вы можете создать исключение ('UnsupportedOperation'?), Если вызов этого метода (метод setter) был выполнен из * неприемлемого контекста *. На самом деле я не думаю, что это хорошая идея: P – TheLostMind

ответ

4

Невозможно определить аргумент только для чтения (только то, что вы уже упоминали). Тем не менее, вы можете использовать builder pattern для создания переданного объекта, чтобы встроенный объект имел только методы getter, поэтому он не будет иметь методы setter, что делает его эффективно неизменным (обратите внимание, что отражение по-прежнему может использоваться для изменения его полей) ,

3

Вы ищете неизменяемость. final гарантирует, что ссылка не может быть обновлена, но изменяемые поля все еще могут быть изменены. Путем создания экземпляров класса неизменяемым вы можете гарантировать, что значение экземпляра никогда не изменится.

Проверить strategy for defining immutable Objects

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

+1

Я думаю, что OP это осознает. – Mena

+0

@Mena - Я думал, что OP знает только о «конечных» полях, а не о неизменяемых экземплярах *. Кроме того, я не вижу никакого хорошего способа сделать это отдельно от использования защитных копий или сделать объект неизменным. – TheLostMind

+0

неизменяемость не является решением, как и в других методах (или где-либо еще в моем приложении). Я хочу, чтобы экземпляры типа изменялись, только в этом вызове метода я не дал «обещание» клиенту, что я не изменю его экземпляр, предоставленный в качестве аргумента – StaticBug

3

Для вас нет чистого Java-решения.

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

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

Есть некоторые (громоздкие) методы, доступные для глубоких клонов коллекций и карт (см. here и here для быстрого примера в SO).

В конечном счете, хорошо представленный и тщательный javadoc может обеспечить соответствующий уровень документации здесь.

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

  • Нет связанных вопросов^_^