我有一个辅助方法, hasContent(String)
,如果其参数为非零,则返回true,并且至少包含一个非Whitespace字符。我刚刚在Eclipse中启用了NULL分析,并且发现当我使用此方法执行一个代码块时,该代码符合我的辅助功能的结果,表明字符串具有内容(因此不能null(,尽管如此,Eclipse抱怨我的字符串仍然可能为空。
助手功能
public static boolean hasContent(String text) {
if (text == null)
return false;
if (text.trim().length() == 0)
return false;
return true;
}
使用示例
...
String dataString;
try {
dataString = readStringFromFile("somefile.txt");
} catch (IOException e) {
System.err.println("Failed to read file due to error: " + e);
dataString = null;
}
// At this point dataString may be null
if (hasContent(dataString)) {
// At this point dataString must be non-null, but Eclipse warns:
// "Potential null pointer access: The variable dataString may be null at this location"
// at the following reference to dataString
System.out.println("Read string length " + dataString.length());
}
...
这种情况的最佳实践是什么?如果我避免了警告,我不想抑制警告。我宁愿告诉Eclipse,如果hasContent()
返回true
,那么它的参数肯定是非null。这可能吗?如果是这样,如何?
您方法的合同是,如果 hasContent
返回true,则保证其参数为非无效。
日食无法在编译时表达或检查此合同,至少没有更改代码并降低其样式。
无效检查器是一个不同的工具,可以在编译时表达和检查此合同。它这样做的情况而不需要您更改代码。您只需添加@EnsuresNonNullIf
注释您的代码:
@EnsuresNonNullIf(expression="#1", result=true)
public static boolean hasContent(String text) { ...
无效检查器与Checker框架分发。有一个Eclipse插件,使您可以在Eclipse中运行无效检查器。
这可能不是最好的做法,但是:如果抛出ioexception,则可以返回false,或者简单地将变量设置为false。如果没有,您可以将变量设置为true(在Try-Block中(。
try {
dataString = readStringFromFile("somefile.txt");
hasContent = true;
} catch (IOException e) {
System.err.println("Failed to read file due to error: " + e);
hasContent = false;
}
我看不到一种方法可以准确地做您正在尝试的事情。
您可以修改hasContent
以返回传递的字符串,而不是a boolean
,如果参数为null或空的,则丢弃Exception
。然后,您将用@NonNull
注释函数。但是,这将以我怀疑您不喜欢的方式妥协您的调用代码,因为它必须使用try
/catch
逻辑而不是if
。
这将使hasContent
功能:
@NonNull
public static String hasContent(String text) throws Exception {
if (text == null)
throw new Exception( "Null string" );
if (text.trim().length() == 0)
throw new Exception( "Empty string" );
return text;
}
和调用代码:
...
try {
dataString = readStringFromFile("somefile.txt");
} catch (IOException e) {
System.err.println("Failed to read file due to error: " + e);
dataString = null;
}
// At this point dataString may be null
try {
dataString = validateHasContent( dataString );
// At this point dataString must be non-null
System.out.println("Read string length " + dataString.length());
} catch( Exception e ) {
}
...
如果您准备做出此妥协,那么一个专用的例外显然会更好。