2012-01-05 11 views
9

Este es el código que he escrito.¿por qué el bloque catch da un error con la variable no inicializada en Java

int num; 
try { 
    num=100; 
    DoSomething(); 
    System.out.println(num); 
} catch(Exception e) { 
    DoSomething1(); 
} finally{ 
    DoSomething2(); 
} 
System.out.println(num); // Error Line 

Me aparece un error 'La variable num local no puede haber sido inicializado' en la línea de error que he mencionado. Al eliminar el bloque catch, el error desaparece. ¿Que esta mal aquí? ¿Estoy haciendo algo incorrecto?

+0

Relacionado, claro. :) –

Respuesta

10

Si se produce una excepción en el bloque try, entonces la variable num puede no haber sido inicializada. Si incluye el bloque catch, la ejecución puede continuar a la línea de error independientemente, y así el compilador informa el error que usted indica.

Si elimina el bloque catch, la ejecución solo alcanzará la "línea de error" si no ha habido una excepción, y en este caso, la variable se habrá inicializado dentro del try.

(Asumo que ya sabe acerca de la necesidad de intialise variables locales antes de usarlos, y se han centrado en el comportamiento notado con el bloque catch ...)

+0

Sí, soy consciente de eso, lo que lo hizo interesante fue el hecho de que al quitar el bloque catch el error desapareció. – gizgok

+0

@gizgok David respondió esto cuando dijo: "Si elimina el bloque catch, la ejecución solo alcanzará la" línea de error "si no ha habido una excepción, y en este caso, la variable se habrá inicializado dentro del intento. " +1 por cierto –

+0

Sí. Espero que la explicación funcione para ti. –

2

Las variables locales en Java no se inicializan automáticamente. Por lo tanto, debe inicializarlo antes de usarlo.

int num=0; 
try 
{ 
    .. 
} 
... 

Para mayor información leer - Definite Assignment (JLS - 16.2.15 try Statements)

+1

Pero él lo está inicializando en 'num = 100;' La ruta de ejecución tampoco tiene bifurcación (ninguna instrucción 'if else'). Entonces java debería saber que 'num' es' 100'. –

+1

@Rosdi - Eso está dentro del bloque try. – adatapost

+0

Conozco la parte de inicialización, estoy más interesado en cómo la eliminación del bloque catch no genera ningún error. – gizgok

0

El problema es que no está num initializated, int num = -1; Y el error desaparecerá;)

+0

Pero la asignación 'num = 100' se ejecuta antes de que se pueda lanzar cualquier excepción. Entonces el bloque catch siempre se ejecutaría * después * de la asignación. –

+0

Como @AVD dijo "Las variables locales en Java no se inicializan automáticamente" – DVD

+0

Sí, pero la variable ** se ** inicializará antes de que se acceda. –

3

El manejo de excepciones puede confundir el compilador. En este caso, usted sabe que no se puede lanzar una excepción ANTES de que se establezca la variable num, pero el compilador no lo sabe.

El compilador cree que puede lanzarse una excepción antes de que se haya configurado num, en cuyo caso num no se habría inicializado cuando intente imprimirlo fuera del bloque try-catch.

+1

* No * sabe que la tarea no puede ejecutarse. Ver el ejemplo de @ FabianBarney para un caso. –

3

En Java debe iniciar local vars. Esto no está garantizado cuando tienes estos bloques catch, ya que se puede lanzar una excepción antes de iniciar la var local en try block y no iniciar la var en el bloque catch. Por lo tanto, es posible que la var local no se haya inicializado después del bloqueo try-catch-finally.

Cuando quita el bloque catch, la var se inicializa después de intentar o se lanza una excepción y el código después de try-block nunca se ejecuta.

Ha siguientes posibilidades para solucionar este problema:

  • init var antes de intentar-bloque
  • init var en Try-Catch-bloques y bloques
  • init var en el bloque finally
  • init var solo en try-block, pero no detecta excepciones

No se garantiza que la var local se inicialice incluso cuando var init is t Lo primero que haces en try-block.Por ejemplo, el hilo ejecutado se puede detener con Thread.stop(Throwable) después de ingresar try-block pero antes var init. Cuando esto sucede, la var no se inicializa, pero se ejecuta catch-finally y el código después de try-catch-finally también.

He aquí un ejemplo para mostrar lo que quiero decir:

public static void main(String[] args) throws InterruptedException { 
    Thread thread = new MyThread(); 

    thread.start(); 
    Thread.sleep(100); 
    thread.stop(new Exception()); 
} 

private static class MyThread extends Thread { 

    @Override 
    public void run() { 
     int num = -1; 

     try { 
      Thread.sleep(600); //just to hit the thread at the right point 
      num = 100; 
      System.out.println("blub"); 
     } 
     catch (Exception e) { 
      System.out.println("catch"); 
     } 
     finally { 
      System.out.println("finally"); 
     } 


     System.out.println(num); 
     System.out.println("after all"); 
    } 

} 

Este código imprime:

catch 
finally 
-1 
after all 
+0

Ejemplo> explicación – yunandtidus

2

Has putten num = 100 dentro del bloque yout try, el compilador asume que un error puede ocurrir antes num = 100 se alcanza. Por lo tanto, cuando ingresa en el bloc Catch, para el compilador, solo ve int num que le da el error Variable not initialized.

+0

¿Qué error podría ocurrir antes de llegar a 'num = 100;' línea? –

+4

@Rosdi Para el compilador, se puede producir cualquier error. Plantación JVM, error interno generado, ... –

1

que pasó a tener blogs sobre esto ayer http://vanillajava.blogspot.com/2012/01/odd-case-of-initialization.html

En resumen, el compilador no sabe si la variable se ha inicializado dentro de un try/catch, incluso en el caso más trivial. Por esta razón, se queja de que la variable podría no haberse inicializado.

Curiosamente, si hace que la variable sea definitiva y trate de establecerla después del bloque try/catch, el compilador se quejará de que se haya inicializado.

+0

, muy interesante introducir el aspecto final a la variable. ¿Por qué pasó esto? ¿Algunas ideas? – gizgok

+0

No se puede establecer una variable final si se ha inicializado y, después de un bloque try/catch, puede inicializarse o no. El compilador simplemente no tiene idea. –

+0

Existe el mal con 'Thread.stop (Throwable)' que puede conducir a un estado donde la var local no se inicializa en el ejemplo dado. –

Cuestiones relacionadas