Java中的try catch块中variables的“范围”有问题

任何人都可以解释为什么在最后一行,br不被认为是variables? 我甚至尝试在try clause中设置br,将其设置为final等。这与Java不支持closures有什么关系? 我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. } } 

谢谢

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

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

br是在try块中定义的,所以它不在finally块的范围内。

在try块之外定义br。

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

首先,如果你在一个传统的try块中声明了一个variables,那么你将不能访问该try块之外的variables。

现在,从Java 7开始,您可以创build一个Try-With-Resources ,它可以缩短代码编写的时间,消除您的“范围”问题,并自动为您closures资源! 在这种情况下的帽子戏法;)

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

注意到现在你甚至不需要担心variables的范围,因为没有必要调用.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 } } 

如果您需要更多关于使用试用资源的解释,请点击这里