考虑一下:
@Nullable Object obj = null;
Optional<Object> optional = Optional.ofNullable(obj);
这会失败,因为 checker-framework 假设 ofNullable
不能接受 null
值(毕竟,它的参数没有标记为 @Nullable)。
是否有一个好方法告诉检查器框架此方法(或遗留代码中我无法更改的其他方法)在各处接受 @Nullable 类型,而不必在各处更改代码?
最佳答案
编辑:这个答案基于评论和Checker Framework's Issue tracker中的@mernst帮助。
如果您像我一样不想或不能使用带注释的 JDK,您将会遇到这个问题。
注意:在我工作过的大多数 Java 商店中,我们根本无法切换使用的编译器或提供“自定义”JDK(这确实是不可想象的)。为了便于移植,对于初学者来说,我必须将自定义 JDK 添加到我的源代码存储库中,或者将其分发到每台计算机,包括编译代码的 CI 服务器,并确保它们在不同的计算机上处于完全相同的路径中。操作系统的。只是不酷。
解决方案是提供stub classes并将它们作为参数传递给 javac
进程。
使用任何编译工具都可以轻松完成此操作。
例如,使用 Maven(使用标准 compiler plugin ):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessors>
<annotationProcessor>org.checkerframework.checker.nullness.NullnessChecker</annotationProcessor>
</annotationProcessors>
<compilerArgs>
<arg>-Astubs=checkerframework/stubs</arg>
<arg>-AstubWarnIfNotFound</arg>
</compilerArgs>
</configuration>
</plugin>
您还需要将这些依赖项添加到您的项目中:
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
<version>1.9.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker</artifactId>
<version>1.9.2</version>
<optional>true</optional>
</dependency>
这里,checkerframework/stubs
是一个目录(相对于pom的位置),包含 stub 。对于Optional,我的 stub 看起来像这样(奇怪的是, stub 必须命名为*.astub,所以这个文件称为Optional.astub):
package java.util;
import org.checkerframework.checker.interning.qual.*;
import javax.annotation.Nullable;
class Optional<T> {
static <T> Optional<T> ofNullable(@Nullable T value);
@Nullable T orElse(@Nullable T other);
}
这种方法很简单,几乎不需要做任何工作,不会与我使用的编译器或 Java 库混淆,确保这些定义仅与 checkerframework 一起使用(例如,我可以将其添加到 Maven配置文件并仅在我想要时通过简单地传递 Maven 参数来启用它),将跨机器和操作系统工作,无需事先以真正的 Java 方式进行设置。
关于java - 如何告诉检查器遗留方法将接受 Nullable 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31158686/