try(PrintWriter f = new PrintWriter(new BufferedWriter(new FileWriter("abc.txt")));)
{}
catch(IOException ex)
{
ex.printStackTrace();
}
以上工作正常。但是当我做的时候
PrintWriter f;
try(f = new PrintWriter(new BufferedWriter(new FileWriter("abc.txt")));)
{}
catch(IOException ex)
{
ex.printStackTrace();
}
它会抛出错误。为什么会这样?我正在测试这个新功能,我认为我会采用第二种方法并在try-catch statement
打印资源PrintWriter f
后 - 如果try-with-resource语句按预期工作,则该值应为null 。为什么不允许第二种方式?
我怎样才能通过方法1进行测试?
答案 0 :(得分:4)
由于try-with-resources
实际上为您添加finally
块以便在使用后关闭资源,因此它们无论如何都不应该可用(在您离开try
块之后)。< / p>
所以这段代码
try(PrintWriter f = new PrintWriter(new BufferedWriter(new FileWriter("abc.txt")));) {
} catch(IOException ex) {
ex.printStackTrace();
}
实际上转化为
PrintWriter f = null;
try {
f = new PrintWriter(new BufferedWriter(new FileWriter("abc.txt")));)
// now do something
} catch(IOException ex) {
ex.printStackTrace();
}
finally {
try {
f.close();
catch(IOException ex) {}
}
}
所以这是最初的目的,除了臃肿的代码,让你只关注try
阻塞,剩下的就放在JVM上了。另请参阅Oracle docs对此有何评论。
答案 1 :(得分:1)
我相信下面的代码可以回答你的问题,并带来意想不到的结果。
PrintWriter t = null;
try( PrintWriter f = new PrintWriter( new BufferedWriter(
new FileWriter( "abc.txt" ) ) ) ) {
f.println( "bar" );
t = f;
} catch( IOException ex ) {
ex.printStackTrace();
}
System.out.println( t );
t.println( "foo" );
t.close();
输出:
java.io.PrintWriter@1fc4bec
但是,没有任何内容添加到文件中,因为编写器已被尝试关闭。
编辑:如果你想玩TWR,写一个实现AutoClosable的类,例如:
public class Door implements AutoCloseable {
public Door() {
System.out.println( "I'm opening" );
}
public void close() {
System.out.println( "I'm closing" );
}
public static void main( String[] args ) {
try( Door door = new Door() ) { }
}
}
输出:
我正在打开
我正在关闭
答案 2 :(得分:0)
不完全确定,但做了一些复杂的猜测:
catch块之后的f值可能未定义。因此,您必须添加各种检查以验证对象是否已创建,使用和/或已关闭。但是如果你需要所有这些检查,那么首先不要使用那个成语会更简单。
JIT可以使用块本地变量愉快地优化代码。
在try块期间,AutoClosure变量不能设置为不同的变量,但可以在之后。也许这对JIT来说太复杂了。