在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
无法正常工作。
有没有办法告诉编译器如果这个验证方法返回true,那么验证的值是非空的?
有没有更好的方法来处理这样的验证方法?
感谢。
为清晰起见而更新:
数据来自用户输入(来自xml或.properties文件),如果数据确实存在,则为null。
永远不会产生null
(例如将其设置为""
)会发明不存在的数据,而且我无法准确地拥有NullString
个对象(可以&# 39; t扩展String
)以表示不存在的数据。
hasText(String s)
必须能够接受任何此输入数据,因此必须能够接受null
。
答案 0 :(得分:1)
这个怎么样?
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 ...
}
}
}
答案 1 :(得分:1)
您的代码是安全的(它永远不会抛出空指针异常),但Eclipse的分析可能太弱而无法确定。您应该考虑使用更强大的工具。
Checker Framework的Nullness Checker可以证明您的代码是安全的。您只需要表达hasText
的约定:hasText
接受一个可能为null的参数,并且只有在其参数为非null时才返回true。
以下是如何表达:
@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 ...
}
}
}