如何让IntelliJ IDEA了解我的空检查方法?

Edw*_*man 6 java nullable intellij-idea

我有一个方法,其中参数用@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这使用JSR 305注释.

在此示例中,在对Intellij 的第一次调用中,useObjectx参数说"参数'x'可能为空" 发出警告.在第二次通话中,没有警告.

mar*_*eck 8

在IDEA 13中添加了一个非常奇特的功能,称为方法合同.例如,您可以使用一个方法,如果遇到null则抛出验证异常:

@Contract("null -> fail")
public static void validateNull(@Nullable final Object object) {
    if (object == null) {
        throw new ValidationException();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您在可能的NPE之前调用注释,IDEA将分析注释并且不会显示警告:

validateNull(user);
user.setSomething("something"); // no warning
Run Code Online (Sandbox Code Playgroud)

您有IDEA设置的完整文档(只需搜索方法合同).为此,您需要额外依赖jetb​​rain的注释jar:

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations</artifactId>
    <version>13.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)


小智 5

随着IDEA 12可以配置NOTNULL检查方法: http://youtrack.jetbrains.com/issue/IDEA-35808#tab=Comments


Mat*_*rne 4

我不相信有任何方法可以用原样编写的代码来解决警告。我希望发现 IntelliJ 支持@SuppressWarnings您可以在语句中使用的值useObject(x),但根据此来源,它不支持。您可能只需要硬着头皮将代码更改为如下所示:

if (x != null && !isBlank(x)) {
    useObject(x);
}
Run Code Online (Sandbox Code Playgroud)

请注意,我将该方法重命名isNullisBlank,因为据我了解,您调用的实际方法也会检查null其他条件。