我正在结合现有的导入和导出函数,以减少在连接被拒绝的情况下用户被告知连接被拒绝的次数。我调用的库具有单独的导入和导出函数,以及组合的导入/导出函数。导出函数需要要导出的文件列表,而组合函数则自行计算出列表(并在内部使用此列表调用导出函数)。由于用户可以关闭导入或导出,因此我只想在必要时获取文件列表。
我想出了这个代码:
List<File> files;
if (mExport)
files = ListFiles();
if (mExport && mImport && files.size() > 0) // Error is on files
DoExportAndImport();
else if (mImport)
DoImport();
else if (mExport && files.size() > 0) // No error here
DoExport(files);
第二个if
语句被标记为错误Variable 'files' might not have been initialized
(但不是最后一个)。
在这里帮助我推理:如果mExport
为真,则files
被初始化;但如果mExport
为假,则第二个if
语句会短路并且永远不会到达files
,所以files
没有被初始化并不重要,因为它没有被使用。
我在这里忽略了一些东西,还是编译器无法解决这种情况太复杂了?如果是后者,有没有办法告诉编译器把它敲掉,我已经处理好了?
为了记录,初始化声明中的files = new ArrayList<>()
确实会使编译器静音,files = null
也是如此,尽管这显然会导致其他错误;但是初始化一个我知道永远不会以任何方式使用或引用的值感觉就像是一种浪费。
您的逻辑是合理的,因为files
将始终在引用files
的每个情况下进行初始化。 但是,正如您所怀疑的那样,编译器并没有走那么远。 它的静态分析不考虑变量的值来确定某个条件是始终为真还是假。
在这种情况下,编译器不会考虑如果true
mExport
则初始化files
。 它只看到files
不是从顶部if
语句初始化的可能性,并且它是该语句下方的引用。
您可以通过重新排列逻辑来提供帮助,以便仅从if
语句块中引用它。
List<File> files;
if (mExport) {
files = ListFiles();
if (mImport && files.size() > 0) {
DoExportAndImport();
} else if (files.size() > 0) {
DoExport(files);
}
} else if (mImport) {
DoImport();
}
静态分析器不是终极AI。有时它可能会给出误报。您应该能够将这一特定行的抱怨静音,但是我建议宁愿重新设计整个代码块的逻辑以使其更简单。
此外files = null
是多余的files
因为除非另有初始化,否则null
。它只是愚弄分析器。