Способы сообщить, что API возвращает неизменяемую/неизменяемую коллекцию

Помимо документирования (очевидно, это также должно быть задокументировано), использования специального типа возвращаемого значения (я опасаюсь ограничивать себя ImmutableX) или предоставления пользователю информации во время выполнения, существует ли какой-либо другой способ сообщить пользователям API, что коллекция, которую они получают от указанного API, является неизменяемой/неизменяемой?

Существуют ли какие-либо соглашения об именах или аннотации маркеров, которые повсеместно обозначают одно и то же?

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


person Celos    schedule 03.06.2015    source источник
comment
Неизменяемый и неизменяемый могут означать разные вещи в Java; Например, Collections.unmodifiableList возвращает неизменяемый, но не неизменяемый объект List — вы не можете вызвать для него add, remove или set, но его содержимое может измениться другими способами.   -  person user253751    schedule 03.06.2015
comment
@immibis, я знаю, но спасибо, что указали на это. Я исправил вопрос с кратким объяснением.   -  person Celos    schedule 03.06.2015


Ответы (4)


Не общее соглашение об именах, но вам может быть интересно использовать эту @Immutable аннотацию: http://aspects.jcabi.com/annotation-immutable.html Помимо целей документирования, этот механизм также проверяет, действительно ли ваш объект является неизменным (во время его создания), и выдает исключение во время выполнения, если это не так.

person flogy    schedule 03.06.2015
comment
Кстати, Immutable присутствует в широко распространенном артефакте Google findbugs maven. - person Victor Sorokin; 03.06.2015

Хорошим и подробным решением было бы создать свой собственный класс-оболочку UnmodifiedCollection и вернуть его:

public UnmodifiableCollection giveMeSomeUnmodifableCollection() {
    return new UnmodifiableCollection(new LinkedList());
}

Имени возвращаемого типа было бы достаточно, чтобы сделать подробное заявление о немодифицируемости коллекции.

person Krzysztof Cichocki    schedule 03.06.2015

  1. Задокументируйте это действительно
  2. Предоставить API для проверки, является ли данный объект неизменяемой коллекцией
  3. Возвращать коллекцию в оболочке, которая будет содержать информацию, является ли коллекция внутри нее изменчивой или нет - мое любимое решение
  4. Если возможно, не используйте изменяемые и неизменяемые коллекции, а выберите одну из них. Результаты всегда могут быть неизменными, поскольку они являются результатами - зачем их менять. Если возникнет такая необходимость, можно одной строкой скопировать коллекцию в новую, изменяемую и изменить ее (например, для обработки цепочки)
person Antoniossss    schedule 03.06.2015
comment
Что касается вашего третьего пункта, я предполагаю, что преимущество некоторой оболочки с методами getX и isMutable по сравнению с возвратом ImmutableX заключается в том, что getX может возвращать собственный интерфейс Collection. Можете ли вы уточнить? - person Celos; 03.06.2015
comment
Определенно, поэтому нет необходимости изобретать велосипед и создавать специальные коллекции. Еще одним преимуществом является гибкость. Если в будущем вы спросите на SO, как уведомлять пользователей API о других метаданных ваших коллекций, вы будете знать, что делать :) Существует разница между неизменяемым и немодифицируемым - оболочка будет очищена, чтобы очистить это. - person Antoniossss; 03.06.2015
comment
Я сомневаюсь в третьем варианте. С одной стороны, он выполняет то, что запрошено, с другой стороны, он добавляет немного запутанный уровень абстракции и заставляет программиста иметь дело с тем, что по сути является ошибкой в ​​​​бизнес-логике (т.е. если он изменчив, то добавьте элемент, иначе .. что? новая, явно изменяемая/модифицируемая коллекция была бы лучше в обоих случаях). - person Celos; 03.06.2015
comment
Это мое четвертое решение - объединить результаты в коллекции одного типа. Самое простое, но возможно ли это в вашем случае - решать только вам - person Antoniossss; 03.06.2015

Написание аннотации @Immutable для возвращаемого типа метода — лучший подход. Он имеет несколько преимуществ:

  • аннотация документирует значение для пользователей
  • инструмент может проверить, что клиентский код соблюдает аннотацию (то есть, клиентский код не содержит ошибок)
  • инструмент может проверить, что код библиотеки соответствует аннотации (то есть код библиотеки не содержит ошибок)

Более того, проверка может выполняться во время компиляции, прежде чем вы запустите свой код.

Если вам нужна проверка во время компиляции, вы можете использовать Проверка неизменности IGJ. Он различает @Immutable< /a> ссылки, абстрактное значение которых никогда не меняется, и @ReadOnly ссылки, на которые нельзя выполнять побочные эффекты.

person mernst    schedule 03.06.2015