"Condition is always false" 编译器发出警告,条件实际上可能为真
"Condition is always false" warning from the compiler on condition which can actually be true
我有一个接口,方法如下:
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("...");
}
...
}
}
编译器向我发出警告说 Condition 'userEmail == null' is always 'false'
,但这看起来不对。
据我了解,如果有人使用 null
值调用我的方法,注释 javax.annotation.Nonnull
将警告编译器,但如果有人传递空值,则不会阻止代码编译给它。所以是的,我的代码在某些时候可以用 null
值调用:
请注意,如果我在命令行上使用选项 -Xlint:all
进行编译,我会收到相同的警告(因此它看起来不像是我的 IDE 中的错误)。
有谁知道我怎样才能摆脱这个警告,为什么会出现这个警告?
免责声明:我展示的例子只是一个例子,实际代码在达到那个条件之前做了一些事情,但没有什么可以让 userEmail == null
总是 false
(正如它所证明的那样我附加的调试器屏幕截图)。
您在方法参数上有注释。 @Nonnull String userEmail
因此它期望 userEmail== null
将始终计算为 false,因此没有理由在那里进行 if 检查。
检查 following answer 关于属于 JSR 305
的 @Nonnull
305 is about new annotations where you can already put them, which
can help provide programmatic visibility into a design by contract
system. So that if a certain method is supposed to not return null, or
if a certain method is supposed to never receive a null parameter
那么如果你作为程序员有信心将那个参数注释为nonNull,为什么它不应该报告检查userEmail == null
没有意义呢?使用注释就像您通知编译器您有信心它永远不会被 null 调用。
注解@Nonnull
就像描述一个合同。您不会签订您知道可能会被破坏的合同。如果您不确定,请删除注释。如果您确定,请取消勾选 userEmail == null
正如很多人在评论中提到的那样。它的行为符合预期。 https://checkerframework.org/manual/#nullness-checker 的解释清楚地说明了这里发生的事情:
The checker issues a warning in these cases:
When an expression of @NonNull type might become null, because it is a misuse of the type: the null value could flow to a dereference that the checker does not warn about.
以上警告仅在您将 -Alint=redundantNullComparison
传递给编译器时出现,并且默认情况下处于关闭状态。当您使用 -Xlint:all
进行编译时,甚至会启用此警告。
如果您不想在 itellij 上看到此警告,您可以更新您的设置:
设置(Ctrl+Alt+S / ⌘) > Editor > Inspections > Java > Declaration redundancy > 使用明显非空参数调用空检查方法。
或
设置(Ctrl+Alt+S / ⌘) > 构建、执行、部署 > 编译器 > 为非空注释方法和参数添加运行时断言
或
设置(Ctrl+Alt+S / ⌘) > 编辑器 > 检查 > Java > 可能的错误
此外,如果您期望空值,那么首先使用该注释似乎不正确。
我有一个接口,方法如下:
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("...");
}
...
}
}
编译器向我发出警告说 Condition 'userEmail == null' is always 'false'
,但这看起来不对。
据我了解,如果有人使用 null
值调用我的方法,注释 javax.annotation.Nonnull
将警告编译器,但如果有人传递空值,则不会阻止代码编译给它。所以是的,我的代码在某些时候可以用 null
值调用:
请注意,如果我在命令行上使用选项 -Xlint:all
进行编译,我会收到相同的警告(因此它看起来不像是我的 IDE 中的错误)。
有谁知道我怎样才能摆脱这个警告,为什么会出现这个警告?
免责声明:我展示的例子只是一个例子,实际代码在达到那个条件之前做了一些事情,但没有什么可以让 userEmail == null
总是 false
(正如它所证明的那样我附加的调试器屏幕截图)。
您在方法参数上有注释。 @Nonnull String userEmail
因此它期望 userEmail== null
将始终计算为 false,因此没有理由在那里进行 if 检查。
检查 following answer 关于属于 JSR 305
的@Nonnull
305 is about new annotations where you can already put them, which can help provide programmatic visibility into a design by contract system. So that if a certain method is supposed to not return null, or if a certain method is supposed to never receive a null parameter
那么如果你作为程序员有信心将那个参数注释为nonNull,为什么它不应该报告检查userEmail == null
没有意义呢?使用注释就像您通知编译器您有信心它永远不会被 null 调用。
注解@Nonnull
就像描述一个合同。您不会签订您知道可能会被破坏的合同。如果您不确定,请删除注释。如果您确定,请取消勾选 userEmail == null
正如很多人在评论中提到的那样。它的行为符合预期。 https://checkerframework.org/manual/#nullness-checker 的解释清楚地说明了这里发生的事情:
The checker issues a warning in these cases: When an expression of @NonNull type might become null, because it is a misuse of the type: the null value could flow to a dereference that the checker does not warn about.
以上警告仅在您将 -Alint=redundantNullComparison
传递给编译器时出现,并且默认情况下处于关闭状态。当您使用 -Xlint:all
进行编译时,甚至会启用此警告。
如果您不想在 itellij 上看到此警告,您可以更新您的设置:
设置(Ctrl+Alt+S / ⌘) > Editor > Inspections > Java > Declaration redundancy > 使用明显非空参数调用空检查方法。
或
设置(Ctrl+Alt+S / ⌘) > 构建、执行、部署 > 编译器 > 为非空注释方法和参数添加运行时断言
或
设置(Ctrl+Alt+S / ⌘) > 编辑器 > 检查 > Java > 可能的错误
此外,如果您期望空值,那么首先使用该注释似乎不正确。