Ответ 1
Благодаря сочетанию аннотаций @Contract
и функции внешних аннотаций вы можете теперь аннотировать методы Preconditions
, чтобы IntelliJ применял правильный статический анализ к вызовам этих методов.
Скажем, у нас есть этот пример
public void doSomething(Object someArg) {
Preconditions.checkArgument(someArg != null);
someArg.doSomethingElse(); //currently gives NPE warning
if (someArg != null) {
//no warning that this is always true
}
}
В IntelliJ (я использую 13):
- Перейдите к
Preconditions.checkArgument(boolean)
. - Поместите курсор на имя метода и нажмите Alt - Enter, чтобы открыть всплывающее окно.
- Выберите "Добавить контракт".
- Используйте текст договора
false -> fail
. - При появлении запроса укажите место для файла внешних аннотаций.
Теперь предупреждение в someArg.doSomethingElse()
исчезает, и IDEA фактически помечает ветвь if
, как всегда, true!
Другие тексты договоров:
-
Preconditions.checkArgument(boolean, String)
должен бытьfalse, _ -> fail
-
Preconditions.checkNotNull(Object, String)
должен бытьnull, _ -> fail
, - и т.д.
Вот мой полный annotations.xml
файл для Preconditions
:
<root>
<item name='com.google.common.base.Preconditions T checkNotNull(T)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val=""null -> fail""/>
</annotation>
</item>
<item name='com.google.common.base.Preconditions T checkNotNull(T, java.lang.Object)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val=""null, _ -> fail""/>
</annotation>
</item>
<item name='com.google.common.base.Preconditions T checkNotNull(T, java.lang.String, java.lang.Object...)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val=""null, _, _ -> fail""/>
</annotation>
</item>
<item name='com.google.common.base.Preconditions void checkArgument(boolean)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val=""false -> fail""/>
</annotation>
</item>
<item name='com.google.common.base.Preconditions void checkArgument(boolean, java.lang.Object)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val=""false, _ -> fail""/>
</annotation>
</item>
<item name='com.google.common.base.Preconditions void checkArgument(boolean, java.lang.String, java.lang.Object...)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val=""false, _, _ -> fail""/>
</annotation>
</item>
<item name='com.google.common.base.Preconditions void checkState(boolean)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val=""false -> fail""/>
</annotation>
</item>
<item name='com.google.common.base.Preconditions void checkState(boolean, java.lang.Object)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val=""false, _ -> fail""/>
</annotation>
</item>
<item name='com.google.common.base.Preconditions void checkState(boolean, java.lang.String, java.lang.Object...)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val=""false, _, _ -> fail""/>
</annotation>
</item>
</root>