Problem with "scopes" of variables in try catch blocks in Java

Could anyone explain me why in the last lines, br is not recognized as variable? I've even tried putting br in the try clause, setting it as final, etc. Does this have anything to do with Java not support closures? I am 99% confident similar code would work in C#.

private void loadCommands(String fileName) {
    try {
        final BufferedReader br = new BufferedReader(new FileReader(fileName));

        while (br.ready()) {
            actionList.add(CommandFactory.GetCommandFromText(this, br.readLine()));
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (br != null) br.close(); //<-- This gives error. It doesn't
                                    // know the br variable.
    }       
}

Thanks


Because it's declared in the try block. Local variables are declared in one block are inaccessible in other blocks except if contained in it, i.e., the variables go out of scope when their block ends. Do this:

private void loadCommands(String fileName) {
    BufferedReader br = null;
    try {
        br = new BufferedReader(new FileReader(fileName));

        while (br.ready()) {
            actionList.add(CommandFactory.GetCommandFromText(this, br.readLine()));
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (br != null) try { br.close(); } catch (IOException logOrIgnore) {}
    }       
}

To update this answer since Java 7 & 8 release:

Firstly, If you declare a variable inside a traditional try{} block you won't have access to that variable outside of that try block.

Now since Java 7 you can create a Try-With-Resources which can shorten your code written, it removes your "scope" problem and it also automatically closes resources for you!!! A Hat Trick in this situation ;)

The equivalent code with Try-With-Resources is:

private void loadCommands(String fileName) {
    try (BufferedReader br = new BufferedReader(new FileReader(fileName))){
        while (br.ready()) {
            actionList.add(CommandFactory.GetCommandFromText(this, br.readLine()));
           }
    } catch (FileNotFoundException e) {
          e.printStackTrace();
    } catch (IOException e) {
          e.printStackTrace();
    } 
}

Notice that now you don't even need to worry about the scope of the variable since there is no need to call .close() it is being automatically done for you!

Any class that implements the AutoClosable interface can be used in a Try-With-Resources block. As a quick example I'll leave this here:

public class Test implements AutoCloseable {

public static void main(String[] args) {
    try (Test t = new Test()) {
        throw new RuntimeException();
    } catch (RuntimeException e) {
        System.out.println(e);
    } catch (Exception e) {
        System.out.println(e);
    }
    System.out.println("The exception was caught and the program continues! :)");
  }

@Override
public void close() throws Exception {
    // TODO Auto-generated method stub
   }
}

If you need more explanation on using try-with-resources click here