如何告诉Checker遗留方法将接受Nullable类型? - java

考虑一下:

@Nullable Object obj = null;
Optional<Object> optional = Optional.ofNullable(obj);

这会失败,因为检查器框架假定ofNullable无法接受null值(毕竟,其参数未标记为@Nullable)。

有没有办法告诉Checker-framework这个方法(或我无法更改的旧代码中的其他方法),在任何地方都可以接受@Nullable类型,而不必在任何地方更改代码?

java大神给出的解决方案

编辑:这个答案是基于@mernst帮助中的注释和Checker Framework's Issue tracker

如果您像我一样,不希望或无法使用带注释的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的位置),其中包含存根。对于Optional,我的存根看起来像这样(奇怪的是,存根必须命名为* .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处事方式进行预先设置即可在机器和OS上运行。

Tomcat找不到直接放置在classes文件夹下的类 - java

我有以下JSP:<%@ page import="foo.*" %> <html> <body> The page count is: <%=Counter.getCount()%> </body> </html> 我在包Counter中有一个foo类,该类存储在: …

无法在Maven surefire中运行多个执行? - java

我想运行名称以ResourceTest.java结尾的测试类,因此我在执行后定义了它们。<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <co…

DataSourceTransactionManager和JndiObjectFactoryBean和JdbcTemplate的用途是什么? - java

以下的用途是什么:org.springframework.jdbc.core.JdbcTemplate org.springframework.jdbc.datasource.DataSourceTransactionManager org.springframework.jndi.JndiObjectFactoryBean <tx:annotatio…

递归泛型类型列表 - java

我有一个通用接口,需要将其类型作为通用参数:interface Base<X extends Base<X>> { X foo(); } class Derived implements Base<Derived> { public Derived foo() { ... } public Derived bar() { …

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…