0
try(PrintWriter f = new PrintWriter(new BufferedWriter(new FileWriter("abc.txt")));) 
{}
catch(IOException ex) 
{
  ex.printStackTrace();
}

Above works fine. But when I do

PrintWriter f;
try(f = new PrintWriter(new BufferedWriter(new FileWriter("abc.txt")));) 
{}
catch(IOException ex) 
{
  ex.printStackTrace();
}

It throws errors. Why is it so? I was testing this new feature and I was of the opinion I would take the 2nd method and after the try-catch statement would print the resource PrintWriter f - which should be null if try-with-resource statement works as expected. Why is the 2nd way not allowed?

Also how could I test it by method 1?

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
  • 1
    [This](http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) might help you, and [this](http://stackoverflow.com/questions/13836486/why-is-declaration-required-in-javas-try-with-resource). – Maroun Oct 17 '13 at 10:16
  • Read more at http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html – Sachin Gorade Oct 17 '13 at 10:19
  • What is the error?That might be helpful – Petr Mensik Oct 17 '13 at 10:21

3 Answers3

4

Because try-with-resources actually adds the finally block for you in order to close the resources after usage, so they should not be usable anyway (after you leave your try block).

So this code

try(PrintWriter f = new PrintWriter(new BufferedWriter(new FileWriter("abc.txt")));) {

} catch(IOException ex) {
    ex.printStackTrace();
}

actually translates into

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) {}
     }
}

So this was the original purpose, save you from the bloated code and allow you to take care just about try block and leave the rest on JVM. Also see what Oracle docs has to say about this.

Petr Mensik
  • 26,874
  • 17
  • 90
  • 115
  • 2
    Your answer shows no reason why it would be forbidden to use an external variable for that. The JVM could still do all that stuff even with a variable from outside. – TwoThe Oct 17 '13 at 10:18
  • I suppose it's because you could bind that variable to something else inside `try` block, like `null` which would mean that JVM will probably not able to close the resouce properly. – Petr Mensik Oct 17 '13 at 10:29
  • Anyway, this has been already asnwered, I was trying to add something new to it - http://stackoverflow.com/questions/13836486/why-is-declaration-required-in-javas-try-with-resource?lq=1 – Petr Mensik Oct 17 '13 at 10:30
1

The code below, I believe, answers your question, with an unexpected result.

    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();

Output:

java.io.PrintWriter@1fc4bec

But, nothing is added to the file, as the writer was closed by the try.

Edit: If you want to play with TWR, write a class that implements AutoClosable, for example:

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() ) { }
    }

}

Output:

I'm opening

I'm closing

Ray Stojonic
  • 1,260
  • 1
  • 7
  • 11
0

Not perfectly sure, but doing some sophisticated guesses:

  • The value of f after the catch block is potentially undefined. Therefore you would have to add all kinds of checks to verify whether the Object has been created, used, and/or is closed. But if you need all those checks, it would be simpler to not use that idiom in the first place.

  • The JIT can happily optimize code with a block-local variable.

  • The AutoClosure variable must not be set to a different variable during the try block, but can be afterwards. Maybe that's just too complicated for the JIT to check.

TwoThe
  • 13,879
  • 6
  • 30
  • 54