今天我写了一个小Java程序来查找硬盘上的文件,部分原因是Windows没有合适的文件,部分原因是为了好玩。它只是遍历目录的所有子节点,如果它们是目录,则递归遍历它们的所有子节点。然后是NullPointerException
。在一些System.out.println()'s
和try-catch block
之后,我发现这种情况发生在一些目录上,如D:System Volume Information
, C:UsersPublicDocumentsMy Videos
和C:ProgramDataTemplates
。当在浏览器地址栏输入"拒绝访问"时,Windows本身会显示。当探索时,它们似乎被锁定了。java.io.File
的来源告诉我:
public File[] listFiles() {
String[] ss = list();
if (ss == null) return null; //This line seems to cause the NPE
int n = ss.length;
File[] fs = new File[n];
for (int i = 0; i < n; i++) {
fs[i] = new File(ss[i], this);
}
return fs;
}
我的问题是,为什么没有适当的说,IOException
, SecurityException
,甚至IDontCareWhatKindOfExceptionButPleaseNoNullPointerExceptionException
?
我知道我可以只try-catch
为NPEs
,或检查null
,但我真的很好奇为什么没有适当的Exception
抛出。
因为我不喜欢try/catch
和检查null
,因为代码的美学价值,我做了一些讨厌的,讨厌的反射代码(有很多虚伪的try/catch
块),它模仿了java.io.File
的一些方法,因为它们是私有的,一些包(如java.io.FileSystem
)是不可见的。因为我不关心一些Windows文件,所以我使用以下代码简单地忽略它们,给我一个空的array
:
public static File[] listFiles(File mThis) {
String[] ss = list(mThis);
if (ss == null) {
//System.out.println("ss is null");
return new File[] {};
}
int n = ss.length;
File[] fs = new File[n];
for (int i = 0; i < n; i++) {
fs[i] = getNewFile(ss[i], mThis);
}
return fs;
}
编辑:为了避免误解:我确实使用try/catch
,我只是不喜欢它们的美学。
EDIT2:我宁愿使用GUI而不是命令提示符。而且我非常不喜欢Windows的搜索GUI。
简短回答:
- 安装JDK使用新的
Files
API。你再也不会回到File
了。
原因是因为API的设计者在函数的契约(文档+签名)中正确地识别了原因:
如果此抽象路径名不表示目录,则此方法返回null。否则返回一个File对象数组,一个用于目录中的每个文件或目录。路径名表示目录本身和目录的父目录不是包含在结果中。每个生成的抽象路径名是使用File(File, String)从这个抽象路径名构造构造函数。因此,如果这个路径名是绝对的,那么每个结果路径名是绝对的;如果这个路径名是相对的,那么每个生成的路径名将相对于相同的目录。
返回null并给出具体原因。
因为我不喜欢try/catch和检查null代码的美学价值
这可能是API的一个"缺点",但你公然无视它,因此你的程序崩溃了。