Пример может быть уточняющим. Рассмотрим следующий код:
class X {
public void main(String[] ss) {
ss[0].toUpperCase(java.util.Locale.ENGLISH);
}
}
Вызов String.toUpperCase()
не изменяет объект ss[0]
, к которому он вызывается, а также не изменяет предоставленный аргумент java.util.Locale.ENGLISH
. Он возвращает новый объект, но этот объект не используется в коде. Вызов не изменяет состояние любых объектов, используемых в программе. Таким образом, удаление вызова не меняет поведение программы. (Строго говоря, он будет работать немного быстрее, но это не считается значимым изменением семантики.)
Обратите внимание, что когда метод main
вызывается с пустым массивом, он вызывает исключение. Когда вызов удален, этого не произойдет. Но исключения не рассматриваются как побочные эффекты для аннотации @Contract
. Исключения можно рассматривать как тип возвращаемого значения.
Таким образом, метод String.toUpperCase()
можно аннотировать как чистый. Чистые методы обрабатываются специально во многих местах в IntelliJ IDEA. Например, если неиспользуемая переменная инициализируется чистым методом, быстрое исправление «знает», что при удалении переменной можно безопасно удалить инициализатор.
Геттеры обычно чистые, void
методы обычно нет. Но есть исключения, например, junit.framework.Assert.fail()
- это void
, но pure
, поскольку он не имеет побочных эффектов. Насколько я знаю, никаких официальных указаний нет.