2012-01-05 6 views
9

Questo è il codice che ho scritto.perché il blocco catch genera un errore con la variabile non inizializzata in Java

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

ottengo un errore 'Il num variabile locale non sia stato inizializzato' sulla linea di errore che ho accennato. Rimuovendo il blocco catch l'errore scompare. Cosa c'è di sbagliato qui? Sto facendo qualcosa di sbagliato?

+0

Correlato, certo. :) –

risposta

10

Se c'è un'eccezione generata nel blocco try, la variabile num potrebbe infatti non essere stata inizializzata. Se includi il blocco catch, l'esecuzione può continuare sulla riga di errore a prescindere, e quindi il compilatore segnala l'errore che hai indicato.

Se si rimuove il blocco catch, l'esecuzione raggiungerà la "riga di errore" solo se non ci sono state eccezioni e, in questo caso, la variabile sarà stata inizializzata all'interno dello try.

(sto supponendo che già si conosce la necessità di intialise variabili locali prima del loro utilizzo, e si sono concentrati sul comportamento avete notato con il blocco catch ...)

+0

Sì, ne sono consapevole, ciò che ha reso interessante il fatto che la rimozione del blocco catch ha fatto sì che l'errore scomparisse. – gizgok

+0

@gizgok David ha risposto quando ha detto: "Se rimuovi il blocco catch, l'esecuzione raggiungerà la" riga di errore "solo se non ci sono state eccezioni e, in questo caso, la variabile sarà stata inizializzata nel tentativo. " +1 btw –

+0

Sì. Spero che la spiegazione funzioni per te. –

2

Le variabili locali in Java non vengono inizializzate automaticamente. Quindi è necessario inizializzarlo prima di usarli.

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

Fore ulteriori informazioni leggere - Definite Assignment (JLS - 16.2.15 try Statements)

+1

Ma lo sta inizializzando a 'num = 100;' Anche il percorso di esecuzione non ha branching (nessuna istruzione 'if else'). Quindi java dovrebbe sapere che 'num' è' 100'. –

+1

@Rosdi - Questo è all'interno del blocco try. – adatapost

+0

Conosco la parte di inizializzazione, sono più interessato a come la rimozione del blocco catch non porti a nessun errore. – gizgok

0

il problema è che non è num initializated, int num = -1; E l'errore andrà via;)

+0

Ma l'assegnazione 'num = 100' viene eseguita prima che possa essere lanciata qualsiasi eccezione. Quindi il blocco catch sarebbe sempre eseguito * dopo * l'assegnazione. –

+0

Poiché @AVD ha affermato che "Le variabili locali in Java non vengono inizializzate automaticamente" – DVD

+0

Sì, ma la variabile ** verrà inizializzata prima di accedervi. –

3

La gestione delle eccezioni può confondere il compilatore. In questo caso, è che un'eccezione non può essere generata PRIMA che la variabile num sia impostata, ma il compilatore non lo sa.

Il compilatore ritiene che possa essere generata un'eccezione prima che num sia stato impostato nel qual caso num non sarebbe stato inizializzato quando si tenta di stamparlo all'esterno del blocco try-catch.

+1

* non * sa che il compito non può non essere eseguito. Vedi l'esempio di FabianBarney per un caso. –

3

In Java è necessario avviare le vars locali. Questo non è garantito quando si hanno questi blocchi catch dal momento che può essere lanciata un'eccezione prima di avviare la var locale nel blocco try e non si inizia la var nel blocco catch. Pertanto la var locale potrebbe non essere stata inizializzata dopo il blocco try-catch-finally.

Quando si rimuove il blocco catch, la variabile viene inizializzata dopo la prova o viene generata un'eccezione e il codice dopo try-block non viene mai eseguito.

Hai seguito le possibilità per risolvere questo problema:

  • init var prima di try-block
  • init var nel try-catch-blocchi e blocchi
  • init var nel blocco finally
  • init var solo in try-block, ma non rilevare eccezioni

La variabile locale non può essere inizializzata anche se var init is t la prima cosa che fai in try-block.Ad esempio, il thread eseguito può essere interrotto con Thread.stop(Throwable) dopo aver inserito try-block ma prima di var init. Quando ciò accade, var non viene inizializzato ma catch-finally viene eseguito e anche il codice dopo try-catch-finally.

Ecco un esempio per mostrare cosa intendo:

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

} 

Questo codice stampa out:

catch 
finally 
-1 
after all 
+0

Esempio> spiegazione – yunandtidus

2

Hai Putten num = 100 all'interno yout try blocco, il compilatore presuppone che potrebbe verificarsi un errore prima num = 100 è stato raggiunto. Quindi, quando si immette nel bloc Catch, per il compilatore, vede solo int num che fornisce l'errore Variable not initialized.

+0

Che errore si può verificare prima di raggiungere 'num = 100;' linea? –

+4

@Rosdi Per il compilatore, si può verificare qualsiasi errore. Impianto JVM, errore interno generato, ... –

1

mi è capitato di aver bloggato su questo ieri http://vanillajava.blogspot.com/2012/01/odd-case-of-initialization.html

In breve, il compilatore non sa se la variabile è stata inizializzata all'interno di un try/catch, anche nel caso più banale. Per questo motivo, si lamenta che la variabile potrebbe non essere stata inizializzata.

È interessante notare che se si imposta la variabile finale e si tenta di impostarla dopo il blocco try/catch il compilatore si lamenterà che potrebbe essere stato inizializzato.

+0

, molto interessante che introduce l'aspetto finale della variabile. Perché succede? Qualche idea? – gizgok

+0

Non è possibile impostare una variabile finale se è stata inizializzata e dopo un blocco try/catch può essere inizializzata o meno. Il compilatore non ha idea. –

+0

C'è il male con 'Thread.stop (Throwable)' che può condurre in uno stato in cui la var locale non è in realtà inizializzata nell'esempio dato. –

Problemi correlati