验证变量空警告
Validated variable null warning
在 Eclipse (4.7.2) 中 null analysis -> potential null access
设置为给我一个警告。
给定以下代码:
public class Test {
// validator method
static boolean hasText(String s) {
return !(s == null || s.trim().isEmpty());
}
public static void main(String[] args) {
// s could come from anywhere and is null iff the data does not exist
String s = (new Random().nextBoolean()) ? "valid" : null;
if (hasText(s)) {
// Potential null pointer access: The variable s may be null at this location
System.out.println(s.length());
// ... do actual stuff ...
}
}
}
如何避免潜在的空警告? @NotNull
将不起作用,因为 null
是有效输入,输出是 boolean
.
有没有办法告诉编译器,如果此验证方法 returns 为真,则验证值不为空?
有没有更好的方法来处理这样的验证方法?
谢谢。
为清楚起见更新:
数据来自用户输入(来自 xml 或 .properties 文件)并且如果数据确实存在则为空。
从不生成 null
(例如,将其设置为 ""
)会发明不存在的数据,而且我不能完全拥有一个 NullString
对象(可以' t 扩展 String
) 来表示不存在的数据。
hasText(String s)
必须能够接受任何此输入数据,因此必须能够接受 null
.
这个怎么样?
public class Test {
// validator method
private static boolean hasText(String s) {
return s != null && !s.trim().isEmpty();
}
public static void main(String[] args) {
String s = (new Random().nextBoolean()) ? "valid" : null;
if (s != null && hasText(s)) {
System.out.println(s.length());
// ... do actual stuff ...
}
}
}
有了这个,您可以将 hasText(String)
方法简化为:
// validator method
private static boolean hasText(String s) {
return !s.trim().isEmpty();
}
另一种选择是避免产生 null
值:
public class Test {
// validator method
private static boolean hasText(String s) {
return !s.trim().isEmpty();
}
public static void main(String[] args) {
String s = (new Random().nextBoolean()) ? "valid" : "";
if (hasText(s)) {
System.out.println(s.length());
// ... do actual stuff ...
}
}
}
您的代码是安全的(它永远不会抛出空指针异常),但 Eclipse 的分析可能太弱而无法确定这一点。您应该考虑使用更强大的工具。
Checker Framework's Nullness Checker可以证明你的代码是安全的。你只需要表达 hasText
的契约: hasText
接受一个 possibly-null 参数,并且它 returns 只有当它的参数是 non-null.[=16 时才为真=]
表达方式如下:
@EnsuresNonNullIf(expression="#1", result=true)
static boolean hasText(@Nullable String s) { ... }
(更多详细信息,请参阅 Javadoc for @EnsuresNonNullIf。)
这是您的完整示例,Nullness Checker 会在没有警告的情况下对其进行验证:
import java.util.Random;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
public class Test {
// validator method
@EnsuresNonNullIf(expression="#1", result=true)
static boolean hasText(@Nullable String s) {
return !(s == null || s.trim().isEmpty());
}
public static void main(String[] args) {
// s could come from anywhere and is null iff the data does not exist
String s = (new Random().nextBoolean()) ? "valid" : null;
if (hasText(s)) {
// Potential null pointer access: The variable s may be null at this location
System.out.println(s.length());
// ... do actual stuff ...
}
}
}
在 Eclipse (4.7.2) 中 null analysis -> potential null access
设置为给我一个警告。
给定以下代码:
public class Test {
// validator method
static boolean hasText(String s) {
return !(s == null || s.trim().isEmpty());
}
public static void main(String[] args) {
// s could come from anywhere and is null iff the data does not exist
String s = (new Random().nextBoolean()) ? "valid" : null;
if (hasText(s)) {
// Potential null pointer access: The variable s may be null at this location
System.out.println(s.length());
// ... do actual stuff ...
}
}
}
如何避免潜在的空警告? @NotNull
将不起作用,因为 null
是有效输入,输出是 boolean
.
有没有办法告诉编译器,如果此验证方法 returns 为真,则验证值不为空?
有没有更好的方法来处理这样的验证方法?
谢谢。
为清楚起见更新:
数据来自用户输入(来自 xml 或 .properties 文件)并且如果数据确实存在则为空。
从不生成 null
(例如,将其设置为 ""
)会发明不存在的数据,而且我不能完全拥有一个 NullString
对象(可以' t 扩展 String
) 来表示不存在的数据。
hasText(String s)
必须能够接受任何此输入数据,因此必须能够接受 null
.
这个怎么样?
public class Test {
// validator method
private static boolean hasText(String s) {
return s != null && !s.trim().isEmpty();
}
public static void main(String[] args) {
String s = (new Random().nextBoolean()) ? "valid" : null;
if (s != null && hasText(s)) {
System.out.println(s.length());
// ... do actual stuff ...
}
}
}
有了这个,您可以将 hasText(String)
方法简化为:
// validator method
private static boolean hasText(String s) {
return !s.trim().isEmpty();
}
另一种选择是避免产生 null
值:
public class Test {
// validator method
private static boolean hasText(String s) {
return !s.trim().isEmpty();
}
public static void main(String[] args) {
String s = (new Random().nextBoolean()) ? "valid" : "";
if (hasText(s)) {
System.out.println(s.length());
// ... do actual stuff ...
}
}
}
您的代码是安全的(它永远不会抛出空指针异常),但 Eclipse 的分析可能太弱而无法确定这一点。您应该考虑使用更强大的工具。
Checker Framework's Nullness Checker可以证明你的代码是安全的。你只需要表达 hasText
的契约: hasText
接受一个 possibly-null 参数,并且它 returns 只有当它的参数是 non-null.[=16 时才为真=]
表达方式如下:
@EnsuresNonNullIf(expression="#1", result=true)
static boolean hasText(@Nullable String s) { ... }
(更多详细信息,请参阅 Javadoc for @EnsuresNonNullIf。)
这是您的完整示例,Nullness Checker 会在没有警告的情况下对其进行验证:
import java.util.Random;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
public class Test {
// validator method
@EnsuresNonNullIf(expression="#1", result=true)
static boolean hasText(@Nullable String s) {
return !(s == null || s.trim().isEmpty());
}
public static void main(String[] args) {
// s could come from anywhere and is null iff the data does not exist
String s = (new Random().nextBoolean()) ? "valid" : null;
if (hasText(s)) {
// Potential null pointer access: The variable s may be null at this location
System.out.println(s.length());
// ... do actual stuff ...
}
}
}