为什么我必须创建输入流和输出流与类型FileReader/Writer当我创建对象本身



好的,这是代码,我的问题是为什么我必须把FileReader inputstream = null;FileWriter相同。为什么不能稍后在try块中简单地创建对象呢?我是不是错过了什么……我可能是。

public static void main(String[] args) throws IOException{
    // TODO Auto-generated method stub
        FileReader inputStream = null;
        FileWriter outputStream = null;
        try {
            inputStream = new FileReader("In.txt");
            outputStream = new FileWriter("Out.txt");
            int c;
            while ((c = inputStream.read()) != -1){
                outputStream.write(c);
            }
        }
                finally {
                    if (inputStream != null){
                        inputStream.close();
                    }
                    if (outputStream != null){
                        outputStream.close();
                }
        }

因为您无法在finally块中引用它们,因此您将无法关闭它们

顺便说一句,如果它们是reader和writer,您最好这样命名变量,而不是xStream

I/O处理一直很乏味,这就是为什么Java 7引入了"try with resource"

因为对于FileReader inputstream = null,您创建对象,而只是一个名为inputStream的对对象的引用。哪一个?无,引用初始化为null。稍后,您可能会或可能不会创建对象(但是如果new FileReader(...)抛出异常会发生什么?);finally块中的检查需要对初始化的变量起作用。

这都是关于明确的分配规则。Java只允许您使用局部变量,如果它可以保证该变量已被初始化。

考虑这个简化版本的代码:

    FileReader inputStream;  // not initialized here ...
    try {
        inputStream = new FileReader("In.txt");
        // do stuff
    } finally {
        if (inputStream != null) {
            inputStream.close();
        }
    }

No假设FileReader构造函数没有找到In.txt文件,并抛出FileNotFoundException。构造函数"异常地"终止,并且没有给inputStream赋值。然后我们到达finally块,在那里我们尝试测试inputStream不是null。但是此时,inputStream仍然是未初始化的,Java不允许我们获取未初始化的局部变量的值,这样就会出现编译错误。

看似无用的null赋值给inputStream,通过确保在到达finally块时始终初始化变量,解决了这个问题。


Java语言规范用了整整一章来说明明确的赋值规则;即编译器用来决定变量是否在任何给定点初始化的规则。这些规则是相当保守的,在某些情况下,编译器会说某些东西没有被明确赋值,而一个大脑发达的人可以推断出它是赋值的。您只需要忍受它,偶尔添加不必要的初始化或永远无法执行的return语句。

我经常使用以下

FileReader in = new FileReader("In.txt");
try {
    // do reading
} finally {
    in.close();
}

这意味着封闭方法抛出IOException(即FileNotFoundException)。这也适用于Java 7:

try (FileReader in = new FileReader("In.txt"); FileWriter ...) {
    // do reading
}

最新更新