Problema con “scope” di variabili in try catch blocks in Java

Qualcuno potrebbe spiegarmi perché nelle ultime righe, br non è riconosciuto come variabile? Ho persino provato a inserire la try clause , impostandola come final , ecc. Ha qualcosa a che fare con Java che non supporta le chiusure? Sono sicuro che il 99% di codice simile funzionerebbe 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. } } 

Grazie

Perché è dichiarato nel blocco try. Le variabili locali sono dichiarate in un blocco sono inaccessibili in altri blocchi tranne se contenute in esso, cioè, le variabili escono dall’ambito di applicazione quando il loro blocco termina. Fai questo:

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

Per aggiornare questa risposta dal rilascio di Java 7 e 8:

Innanzitutto, se dichiari una variabile all’interno di un blocco try {} tradizionale, non avrai accesso a quella variabile al di fuori di quel blocco try.

Ora da quando Java 7 è ansible creare una Try-With-Resources che può abbreviare il codice scritto, rimuove il problema “scope” e inoltre chiude automaticamente le risorse per te !!! A Hat Trick in questa situazione;)

Il codice equivalente con 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(); } } 

Si noti che ora non è nemmeno necessario preoccuparsi della portata della variabile poiché non è necessario chiamare .close () viene automaticamente eseguita per te!

Qualsiasi class che implementa l’interfaccia AutoClosable può essere utilizzata in un blocco Try-With-Resources. Come esempio rapido lascerò questo qui:

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

Se hai bisogno di ulteriori spiegazioni sull’uso di try-with-resources clicca qui

br è definito nel blocco try in modo che non sia incluso nell’oscilloscopio nel blocco finally.

Definire br al di fuori del blocco try.