web-dev-qa-db-ja.com

Javaのtrycatchブロックの変数の「スコープ」に関する問題

最後の行で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.
    }       
}

ありがとう

21

Tryブロックで宣言されているためです。 1つのブロックで宣言されたローカル変数は、他のブロックに含まれている場合を除いて、他のブロックではアクセスできません。つまり、変数は、ブロックが終了するとスコープ外になります。これを行う:

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

Java 7&8リリース以降この回答を更新するには:

まず、従来のtry {}ブロック内で変数を宣言すると、そのtryブロック外ではその変数にアクセスできなくなります。

Java 7)を作成して、記述したコードを短縮できるTry-With-Resourcesを作成できるため、「スコープ」の問題が解消されます。また、自動的にリソースを閉じます!!!この状況でのハットトリック;)

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の使用についてさらに説明が必要な場合は、 ここ をクリックしてください。

3
Top_Pug

brはtryブロックで定義されているため、finallyブロックのスコープには含まれていません。

Tryブロックの外側でbrを定義します。

1
ZZ Coder