我有一个方法,其中参数用@Nonnull
注释标记。调用该方法的代码必须检查该值是否为null。它不是直接x != null
检查,而是在另一个类上调用实用程序方法。 (在实际代码中,实用程序方法还会检查它是否为空字符串。)
我的问题是Intellij Idea在Nonnull方法调用上显示检查警告,说我的变量“可能为null”。我知道它不能为空因为实用方法检查 - 我该如何告诉检查员?
因为这有点抽象,所以这是我的意思的最小例子:
package org.ethelred.ideatest;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
* tests annotations
*/
public class AnnotationChecker
{
public static void main(String[] args)
{
String x = null;
if(args.length > 0)
{
x = args[0];
}
if(!isNull(x))
{
useObject(x);
}
if(x != null)
{
useObject(x);
}
}
public static boolean isNull(@CheckForNull Object o)
{
return o == null;
}
public static void useObject(@Nonnull Object o)
{
System.out.println(o);
}
}
这使用JSR 305注释。
在此示例中,在第一次对useObject
的调用中,Intellij对x
参数发出警告,说“参数'x'可能为空”。在第二次调用中,没有警告。
答案 0 :(得分:7)
在IDEA 13中添加了一个非常奇特的功能,称为Method Contracts。例如,您可以使用一个方法,如果遇到null,则抛出验证异常:
@Contract("null -> fail")
public static void validateNull(@Nullable final Object object) {
if (object == null) {
throw new ValidationException();
}
}
如果您在可能的NPE之前调用注释,IDEA将分析注释并且不会显示警告:
validateNull(user);
user.setSomething("something"); // no warning
您在IDEA的设置中拥有完整的文档(只需搜索方法合约)。为此,您需要额外依赖jetbrain的注释jar:
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
</dependency>
答案 1 :(得分:5)
使用IDEA 12,您可以配置NotNull检查方法: http://youtrack.jetbrains.com/issue/IDEA-35808#tab=Comments
答案 2 :(得分:3)
我不相信有任何方法可以用编写的代码来解决警告。我希望发现IntelliJ支持@SuppressWarnings
可以在useObject(x)
语句中使用的值,但根据this source,它不支持。if (x != null && !isBlank(x)) {
useObject(x);
}
。您可能只需咬紧牙关并将代码更改为以下内容:
isNull
请注意,我已将方法isBlank
重命名为null
,因为我理解您正在调用的实际方法检查{{1}}也会检查其他条件。< / p>
答案 3 :(得分:-1)
我通过使用静态方法将对象调用列入白名单来解决此问题:
/** Wrapper to mask NullPointerException warnings. */
private static <T> T _(T obj) {
return obj;
}
方法名称旨在不干扰可读性。因此,
mObject.method();
变为
_(mObject).method();
此外,如果确实发生NullPointerException,它仍然会引用相同的行号。