在单行中调用 Optional#isPresent() 被报告为未调用
Calling Optional#isPresent() in single line is reported as not called
我 运行 SonarQube 检查我的代码,我发现了一个我不理解报告错误的案例。
我的代码是:
private static final int BASE_ID = 100_000_000;
private boolean isValidId(Id id) {
return id.asInteger().isPresent() && id.asInteger().get() >= BASE_ID;
}
方法asInteger
returnsOptional<Integer>
我从 sonarqube 得到的错误是
Call "Optional#isPresent()" before accessing the value.
在 return 行。
我知道代码没问题,因为如果第一部分为假,if
的第二部分将不会执行。我知道这可以用 .filter(..).isPresent()
解决,但我更喜欢这种方式。
知道为什么会发生这种情况吗?
顺便说一下,你可以把它写成一条语句:
return id.asInteger()
.map(x -> x >= BASE_ID)
.orElse(false)
但是声纳抱怨是因为在这种情况下它是误报。
Sonarqube 不能保证两次调用 id.asInteger()
returns 是同一个对象,例如因为多线程可能在两次调用之间更改了 id
的值,所以它正确地说明了存在尚未得到充分测试。
更改代码以首先分配给局部变量,以确保 isPresent()
和 get()
在同一对象上调用:
private boolean isValidId(Id id) {
Optional<Integer> idAsInteger = id.asInteger();
return idAsInteger.isPresent() && idAsInteger.get() >= BASE_ID;
}
在使用 Optionals 时,您应该尽可能避免使用 .isPresent
和 .get
。使用这些方法并不比使用 null 更安全,并且有悖于功能精神。可选项用于函数式编程和空检查的类型安全替代。
SonarQube 的分析功能有限。它通常不能排除各种误报。这种情况并不是真正的问题,因为不建议以这种方式使用 Optionals。
为了避免这个问题,我使用 iterator().next() 它具有与 .get 相同的功能,但它没有 isPresent() 问题!
我 运行 SonarQube 检查我的代码,我发现了一个我不理解报告错误的案例。
我的代码是:
private static final int BASE_ID = 100_000_000;
private boolean isValidId(Id id) {
return id.asInteger().isPresent() && id.asInteger().get() >= BASE_ID;
}
方法asInteger
returnsOptional<Integer>
我从 sonarqube 得到的错误是
Call "Optional#isPresent()" before accessing the value.
在 return 行。
我知道代码没问题,因为如果第一部分为假,if
的第二部分将不会执行。我知道这可以用 .filter(..).isPresent()
解决,但我更喜欢这种方式。
知道为什么会发生这种情况吗?
顺便说一下,你可以把它写成一条语句:
return id.asInteger()
.map(x -> x >= BASE_ID)
.orElse(false)
但是声纳抱怨是因为在这种情况下它是误报。
Sonarqube 不能保证两次调用 id.asInteger()
returns 是同一个对象,例如因为多线程可能在两次调用之间更改了 id
的值,所以它正确地说明了存在尚未得到充分测试。
更改代码以首先分配给局部变量,以确保 isPresent()
和 get()
在同一对象上调用:
private boolean isValidId(Id id) {
Optional<Integer> idAsInteger = id.asInteger();
return idAsInteger.isPresent() && idAsInteger.get() >= BASE_ID;
}
在使用 Optionals 时,您应该尽可能避免使用 .isPresent
和 .get
。使用这些方法并不比使用 null 更安全,并且有悖于功能精神。可选项用于函数式编程和空检查的类型安全替代。
SonarQube 的分析功能有限。它通常不能排除各种误报。这种情况并不是真正的问题,因为不建议以这种方式使用 Optionals。
为了避免这个问题,我使用 iterator().next() 它具有与 .get 相同的功能,但它没有 isPresent() 问题!