2010-05-18 18 views
20

¿Alguien podría explicarme por qué en las últimas líneas, br no se reconoce como variable? Incluso he intentado poner br en el try clause, configurándolo como final, etc. ¿Tiene esto algo que ver con que Java no admita cierres? Estoy 99% seguro de que un código similar funcionaría en C#.Problema con "ámbitos" de variables en try catch blocks en Java

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

Gracias

+3

C# tiene una palabra clave 'using' que, como un bucle, permite usted para definir una variable limitada por el alcance posterior. Java no tiene eso. – Yishai

+0

Por cierto: yo no haría 'e.printStackTrace()' aquí. Su programa continuará ejecutándose posiblemente con una lista de acciones vacía. No quieres tener eso. Solo visualice y deje que su aplicación se cierre o se bloquee con un mensaje de error claro para que el usuario final pueda tomar las medidas correspondientes. – BalusC

+0

Todavía no sé cómo se supone que debo tratar con excepciones en Java. En C#, dejaría que esto subiera en la pila, pero si quiero hacer eso, tendré que poner una declaración de lanzamientos en esta función y en cualquier función que llame a esta. Es un PITA. –

Respuesta

40

Porque está declarado en el bloque try. Las variables locales declaradas en un bloque son inaccesibles en otros bloques, excepto si están contenidas en él, es decir, las variables quedan fuera del alcance cuando finaliza su bloque. Haga lo siguiente:

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

Estaba casi seguro de que intenté con el mismo código aquí y no funcionó. ¡Bien gracias! –

+0

bien, genial. Ahora no me deja hacer el br.close() sin rodearlo en otro bloque try catch. ¿Que se supone que haga? –

+0

Simplemente ponga ese otro bloque try/catch en;) – BalusC

1

ancho se define en el bloque try así que no es en el ámbito en el bloque finally.

Defina br fuera del bloque try.

0

Para actualizar esta respuesta ya que Java 7 8 & liberación:

primer lugar, si se declara una variable dentro de un try {} bloquear tradicional que no tendrá acceso a esa variable fuera de que intenta bloquear.

Ahora desde Java 7 puede crear un Try-With-Resources que puede acortar su código escrito, elimina su problema de "alcance" y también cierra automáticamente los recursos para usted! Una tripleta en esta situación;)

El código equivalente con Try-Con-Recursos es:

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

en cuenta que ahora ni siquiera tiene que preocuparse por el alcance de la variable ya que no hay necesidad de llamar .close() ¡se está haciendo automáticamente para usted!

Cualquier clase que implemente la interfaz AutoClosable se puede usar en un bloque Try-With-Resources. Como un ejemplo rápido Voy a dejar esto aquí:

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

Si necesita más explicaciones sobre el uso de try-con-recursos clic here