简体   繁体   English

为什么java.io.File.listFiles()抛出NPE而不是适当的异常?

[英]Why does java.io.File.listFiles() throw NPE instead of proper Exception?

Today I wrote a small Java program to find files on my harddisk, partly because Windows lacks a proper one and partly because it was for fun. 今天,我编写了一个小的Java程序来在硬盘上查找文件,部分原因是Windows缺少适当的文件,部分原因是出于娱乐目的。 It simply iterates over all childs of a directory and recursively through all their children if they are directories. 它只是简单地遍历目录的所有子项,如果它们是目录,则循环遍历所有子项。 But then I had a NullPointerException . 但是后来我有了NullPointerException After some System.out.println()'s and a try-catch block I found out this happened on some directories like D:\\System Volume Information , C:\\Users\\Public\\Documents\\My Videos and C:\\ProgramData\\Templates . 经过一些System.out.println()'s和一个try-catch block我发现这发生在某些目录中,例如D:\\System Volume InformationC:\\Users\\Public\\Documents\\My VideosC:\\ProgramData\\Templates Windows itself says, when input in the Explorer address bar "Access denied". 当在资源管理器地址栏中输入“拒绝访问”时,Windows本身会说。 When exploring , they seem to be locked. 探索时 ,它们似乎已被锁定。 The source from java.io.File tells me: 来自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;
}

My question is, why is there no proper say, IOException , SecurityException , or even an IDontCareWhatKindOfExceptionButPleaseNoNullPointerExceptionException ? 我的问题是,为什么没有适当的说法, IOExceptionSecurityException甚至IDontCareWhatKindOfExceptionButPleaseNoNullPointerExceptionException

I know I can just try-catch for NPEs , or check for null , but I'm really curious of why there's no proper Exception thrown. 我知道我可以try-catch NPEs或检查null ,但是我很好奇为什么没有适当的Exception抛出。

Since I dislike try/catch and checking for null because of the aesthetic value of code, I made some nasty, nasty reflection code (with lots of hypocritical try/catch blocks) which emulates some methods from java.io.File , since they're private, and some packages (like java.io.FileSystem ) are not visible. 由于由于代码的美学价值,我不喜欢try/catch和检查null ,因此我制作了一些讨厌的,讨厌的反射代码(带有许多虚伪的try/catch块),它们模仿了java.io.File某些方法,因为它们重新私有化,某些包(如java.io.FileSystem )不可见。 And because I do not care about some Windows files, I simply ignore them using this code, giving me an empty array : 而且由于我不在乎某些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;
}

EDIT: to avoid misinterpretations: I do use try/catch , I merely don't like them aesthetically. 编辑:为避免误解:我确实使用try/catch ,从审美角度try/catch ,我只是不喜欢它们。

EDIT2: I'd rather use a GUI than the command prompt. EDIT2:我宁愿使用GUI而不是命令提示符。 And I very much dislike the Windows Search GUI. 而且我非常不喜欢Windows Search GUI。 It's almost painful to use. 使用几乎是痛苦的。

Short answer: 简短答案:

  • install JDK 7; 安装JDK 7;
  • use the new Files API. 使用新的Files API。

You will never come back to File after that. 之后,您将永远不会再回到File

The reason why is because the designers of the API correctly identified the reason in the contract of the function (documentation + signature): 原因是因为API的设计者正确地在功能合同(文档+签名)中确定了原因:

If this abstract pathname does not denote a directory, then this method returns null. 如果此抽象路径名不表示目录,则此方法返回null。 Otherwise an array of File objects is returned, one for each file or directory in the directory. 否则,将返回File对象的数组,该对象对应目录中的每个文件或目录。 Pathnames denoting the directory itself and the directory's parent directory are not included in the result. 表示目录本身和目录的父目录的路径名不包括在结果中。 Each resulting abstract pathname is constructed from this abstract pathname using the File(File, String) constructor. 使用File(File,String)构造函数从此抽象路径名构造每个结果抽象路径名。 Therefore if this pathname is absolute then each resulting pathname is absolute; 因此,如果此路径名是绝对路径,则每个结果路径名称都是绝对路径; if this pathname is relative then each resulting pathname will be relative to the same directory. 如果此路径名是相对的,则每个结果路径名将相对于同一目录。

It returns null and it gives the specific reason why. 它返回null并给出具体原因。

Since I dislike try/catch and checking for null because of the aesthetic value of code 由于代码的美学价值,我不喜欢尝试/捕获并检查null

It may be a "short-coming" of the API but you blatantly disregarded it and as such your program crashes. 它可能是API的“缺点”,但是您公然忽略了它,因此程序崩溃了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM