【问题标题】:Checker Framework argument.type.incompatible undesired positiveChecker 框架参数.type.incompatible 不受欢迎的正面
【发布时间】:2020-12-09 20:22:35
【问题描述】:

所以我从空值检查器中得到了这个错误

> Task :compileJava
/Users/calebcushing/IdeaProjects/ppm/scaf/src/main/java/com/xenoterracide/scaf/PebbleTemplateProcessor.java:94: error: [argument.type.incompatible] incompatible argument for parameter obj of requireNonNull.
        var console = Objects.requireNonNull( System.console() );
                                                            ^                                     ^

这是在抱怨System.console() 可能为空,这在阅读 javadoc 时是正确的。所以我把它包裹在Objects.requireNonNull() 现在它抱怨requireNonNull 的参数不能为空,这显然不是真的。

如何告诉NullnessChecker 忽略Objects.requireNonNull()?我对明确的 NPE 很好,这只是我不想要的偶然的。我相信 checker 已经为此提供了一个存根。

【问题讨论】:

    标签: java checker-framework


    【解决方案1】:

    意识到我迟到了,但希望这会帮助其他在搜索后登陆这里的人。

    您可以向 Checker 提供一个stub file,它会覆盖默认注释。

    对于我自己的项目,我在我的一个常见项目中的src 文件夹旁边创建了一个名为checker 的新文件夹,并放入包含以下内容的存根文件java.util.Objects.astub

    package java.util;
    
    import org.eclipse.jdt.annotation.Nullable;
    
    public class Objects
    {
       public static <T> T requireNonNull(@Nullable T obj, String message);
    }
    

    然后我将它添加到我们的 Gradle 构建中:

    checkerFramework {
       extraJavacArgs = [
          "-Astubs=${project(':my-project').file('checker')}"
       ]
    }
    
    

    ...my-project 是包含新文件夹的项目的 Gradle 标识符。

    Checker 现在将加载该 checker 文件夹中的所有 *.astub 文件,并使用那里提供的注释而不是默认值。您可以在 Checker 文档中的 Using Stub Classes 了解更多信息。

    【讨论】:

      【解决方案2】:

      编辑:以下答案是为原始帖子编写的,其中包含 3 个不相关的问题。 (发帖人后来编辑了原帖。)我不知道为什么这个答案被否决了,因为它准确地回答了所有 3 个问题,并提供了更多信息的链接。

      请咨询one question per post

      第一个抱怨System.console() 可能为空,这在阅读 javadoc 时是正确的。所以我把它包裹在Objects.requireNonNull() 现在它抱怨requireNonNull 的参数不能为空,这显然不是真的。

      这在introduction to the Checker Framework manual中得到了回答。

      Nullness Checker 的目标是在您的程序可能抛出 NullPointerException 时发出警告。 如果requireNonNull() 的参数是null,那么您的程序将抛出NullPointerException。 因此,将null 传递给requireNonNull() 不会比将null 传递给任何其他可能取消引用它的例程更正确,并且Nullness Checker 会发出警告。

      您试图通过写requireNonNull() 来消除警告。 如上所述,这没有任何效果:程序仍然抛出NullPointerException。 相反,最好纠正根本问题。您的程序应该检查 null 并发出用户友好的消息而不是崩溃——无论崩溃是在您自己的代码中还是在 requireNonNull() 中。

      第二个是抱怨 commons-lang3 参数不能取 null,但它的文档另有说明。

      introduction to the Checker Framework manual 也回答了这个问题。

      Nullness Checker 读取注释,而不是英语 Javadoc cmets。 为了让 Nullness Checker 知道 toBoolean() 可以接受 null 参数,它的 toBoolean() 签名需要注释为:

      boolean toBoolean(@Nullable Boolean bool)
      

      the manual 中所述,您可以编写该注释,以便 Nullness Checker 使用它。 您还可以将 commons-lang 注释回馈给社区,以便其他人也可以从中受益。

      我添加了 SuppressWarnings,不知道为什么它仍然会发生。

      您需要在发出警告的地方写上@SuppressWarnings,它位于Application 类的声明中。你在程序的另一行写了@SuppressWarnings

      【讨论】:

      • Re: commons-lang3 我知道它不读取 cmets.. 写这个的时候我很累。在上游补丁之外我该如何解决这个问题?
      • 请参阅我在答案中链接到的chapter of the manual。您可能想要创建一个存根文件,那里有描述。
      • > 重要链接最相关的部分,以防外部资源无法访问或永久离线How To Answer (SO)
      • @SuppressWarnings("initialization.fields.uninitialize") 我试着把它放在构造函数和类上,我仍然收到这个错误。 /Users/calebcushing/IdeaProjects/ppm/scaf/src/main/java/com/xenoterracide/scaf/Application.java:24: error: [initialization.fields.uninitialized] the constructor does not initialize fields: arg, args, dir Application() { ^
      • 如果你想把你的答案部分移到这里stackoverflow.com/q/65245465/206466
      猜你喜欢
      • 2010-09-07
      • 2021-02-20
      • 1970-01-01
      • 1970-01-01
      • 2020-10-16
      • 1970-01-01
      • 2017-05-30
      • 2021-10-11
      • 1970-01-01
      相关资源
      最近更新 更多