Конструкции языка Java, указывающие на то, что аргумент не будет изменен?

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

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

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

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

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


person StaticBug    schedule 18.11.2015    source источник
comment
вы можете сделать глубокую копию и передать это.   -  person John    schedule 18.11.2015
comment
Один грязный способ - использовать StackTraceElement, чтобы извлечь последний вызванный метод / класс. Вы можете вызвать исключение (UnsupportedOperation?), Если вызов этого метода (метода установки) был выполнен из недопустимого контекста. На самом деле я не думаю, что это хорошая идея: P   -  person TheLostMind    schedule 18.11.2015


Ответы (3)


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

person Gergely Kőrössy    schedule 18.11.2015

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

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

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

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

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

person Mena    schedule 18.11.2015

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

Проверьте стратегию определения неизменяемых объектов

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

person TheLostMind    schedule 18.11.2015
comment
Я думаю, что OP знает об этом. - person Mena; 18.11.2015
comment
@Mena - я думал, что OP знает только о final полях, а не о неизменяемых экземплярах. Кроме того, я не вижу никакого хорошего способа сделать это, кроме использования защитных копий или создания неизменяемого объекта. - person TheLostMind; 18.11.2015
comment
неизменяемость не является решением, как и в других методах (или где-либо еще в моем приложении), я хочу, чтобы экземпляры этого типа были изменяемыми, только в этом вызове метода я не хочу давать обещание клиенту, которое я выиграл не меняет его экземпляр, предоставленный в качестве аргумента - person StaticBug; 18.11.2015
comment
@StaticBug - затем используйте защитные копии ваших экземпляров, такие как Mena - person TheLostMind; 18.11.2015