Java中try catch块中变量“范围”的问题

时间:2010-05-18 01:55:02

标签: java try-catch

有人可以解释为什么在最后几行中,br不被识别为变量吗?我甚至尝试将br放在try clause中,将其设置为final等等。这与Java有什么关系不支持闭包吗?我99%有信心类似的代码可以在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.
    }       
}

由于

3 个答案:

答案 0 :(得分:40)

因为它在try块中声明。在一个块中声明的局部变量在其他块中是不可访问的,除非包含在其中,即,当块结束时变量超出范围。这样做:

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

答案 1 :(得分:2)

自Java 7和Java 7以来更新此答案8发布:

首先,如果您在传统的try {}块中声明了一个变量,那么您将无法访问该try块之外的该变量。

现在,从Java 7开始,您可以创建一个 Try-With-Resources ,它可以缩短您编写的代码,它会删除您的&#34;范围&#34;问题,它也会自动为您关闭资源!在这种情况下的帽子技巧;)

Try-With-Resources 的等效代码是:

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

请注意,现在您甚至不必担心变量的范围,因为无需调用.close()它会自动为您完成!

任何实现AutoClosable接口的类都可以在Try-With-Resources块中使用。作为一个简单的例子,我将把它留在这里:

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

如果您需要有关使用try-with-resources的更多说明,请点击here

答案 2 :(得分:1)

br在try块中定义,因此它不在finally块的范围内。

在try块之外定义br。