Java &引用;“条件总是错误的”;编译器发出的警告,条件可能为真
我有这样一个方法的接口:Java &引用;“条件总是错误的”;编译器发出的警告,条件可能为真,java,compiler-warnings,Java,Compiler Warnings,我有这样一个方法的接口: public interface MyInterface { void myMethod(@Nonnull String userEmail); } 该接口具有以下实现: public class MyInterfaceImpl implements MyInterface { @Override public void myMethod(@Nonnull String userEmail) { if ((userEmail==
public interface MyInterface {
void myMethod(@Nonnull String userEmail);
}
该接口具有以下实现:
public class MyInterfaceImpl implements MyInterface {
@Override
public void myMethod(@Nonnull String userEmail) {
if ((userEmail== null) || !userEmail.endsWith("something")) {
throw new SomeException("...");
}
...
}
}
编译器向我发出警告说,条件“userEmail==null”总是“false”
,但这看起来不对
据我所知,注释javax.annotation.Nonnull
将在有人使用null
值调用我的方法时警告编译器,但如果有人向其传递null值,则不会阻止代码编译。因此,是的,我的代码可以在某个点用null
值调用:
请注意,如果我在命令行上使用选项
-Xlint:all
进行编译,则会收到相同的警告(因此它看起来不像是IDE中的一个bug)
有人知道我怎样才能摆脱这个警告吗?为什么会这样
免责声明:我展示的示例只是一个示例,实际代码在达到该条件之前做了一些事情,但是没有任何东西可以使
userEmail==null
始终false
(正如我附带的调试器屏幕截图所证明的那样)。您在方法参数上有注释@非空字符串userEmail
因此,它期望userEmail==null
的计算结果总是为false,因此没有理由出现在if检查中
检查有关属于JSR 305的@Nonnull
的
305是关于新的注释,您可以在其中放置它们,这
可以帮助提供合同设计的程序可视性
系统。如果某个方法不应该返回null,或者
如果某个方法被认为永远不会接收空参数
因此,如果作为程序员,您有信心将该参数注释为非null,为什么它不报告checkuserEmail==null
没有任何意义?使用注释就像通知编译器您有信心永远不会使用null调用它
注释
@Nonnull
类似于描述合同。你不会签订你知道会被破坏的合同。如果不确定,请删除注释。如果确定,请删除复选框userEmail==null
,因为评论中已经提到了很多人。它的行为符合预期。来自的解释清楚地说明了这里发生了什么:
在这些情况下,检查器会发出警告:
当@NonNull类型的表达式可能变为null时,因为它是对该类型的误用:null值可能会流向一个取消引用,而检查器不会对此发出警告
只有将-Alint=redundantNullComparison
传递给编译器时,上述警告才会显示,并且默认情况下处于关闭状态。当您使用-Xlint:all进行编译时,即使此警告已启用
如果不想在itellij上看到此警告,可以更新设置:
设置(Ctrl+Alt+S/⌘) > 编辑器>检查>Java>声明冗余>空检查方法使用明显非空参数调用
或
设置(Ctrl+Alt+S/⌘) > 生成、执行、部署>编译器>为非空注释的方法和参数添加运行时断言
或
设置(Ctrl+Alt+S/⌘) > 编辑器>检查>Java>可能的错误
另外,如果您期望一个空值,那么首先使用该注释似乎是不对的。@ruakh Java version:11.0.2-BellSoft,vendor:BellSoft,runtime:C:\jdk-11.0.2哪个@Nonnull
是这样的注释?我认为源代码级别的注释是这样的(比如lombok给出的注释)实际上,生成一个检查代码中是否有null的if
块。如果是这种情况,那么编译器是正确的。您可能需要对类文件进行反编译,以查看最终的代码。@ernest_k:Lombok的注释处理器仅对Lombok自己的@NonNull执行此操作。javax.annotation.NonNull
(OP正在使用的)没有这种行为。@Nonnull不会按照您的想法执行。它会告诉编译器它应用的参数不能为null。因此您的==null
测试不能为真。因为如前所述,您打开了linter。这将保证正确性,并使if
冗余。非常感谢您花时间编写答案。正如我在问题主体和评论中所述,我使用的是javax.annotations.Nonnull
,而不是org.checkerframework.checker.nullness.qual.Nonnull
,这正是您在回答中提到的值。此外,我不期望null
值(这就是为什么我用@Nonnull
进行注释,以便我的服务的客户端在传递null
时会看到编译器警告),但我不能确定是否有人会发送它,如果是这样,我想发送一个明确的异常,说明我为什么不接受他们的请求(这就是我在代码中检查null
的原因)。@MatteoNNZ此注释仅用于linting和警告。如果要引发异常,可以使用lambok的notNull或Objects。requirennull(object);我的输入字符串需要验证,我需要调用endsWith()因此,如果使用空字符串调用我,我将面临空指针异常的风险。我希望捕获空字符串/无效字符串,并发送一个特定的异常,而不仅仅是NPE,这就是为什么我首先使用if null条件编写代码的原因。无论如何,似乎没有人能像我一样看到它:)看起来我是唯一一个看到这种情况的人,但我真的没有得到一点。将参数注释为@Nonnull将使编译器警告任何使用null值调用我的方法的人,他们正在将null传递到一个不需要null的方法中。这很好。但它实际上并不阻止任何人发送null值。