2013-02-27 8 views
5

Eclipse 4 dà un avvertimento che dice il stmt non può potenzialmente essere chiusi e causare una perdita di risorse:In base a quale circostanza potrebbe fuoriuscire questa risorsa?

class Test { 
    public void test() { 
     PreparedStatement stmt = null; 
     try { 
      stmt = HibernateSession.instance().connection().prepareStatement(""); 
     } catch (final SQLException e) { 
      e.printStackTrace(); 
     } finally { 
      if (stmt != null) 
       try { 
        stmt.close(); 
       } catch (final SQLException e) { 
        e.printStackTrace(); 
       } 
     } 
    } 
} 

In quale circostanza potrebbe succedere?

+1

non è il peggiore bug di Eclipse –

+1

@OlegMikheev che non è un bug, questa è una funzionalità. E non intendo questo sarcasticamente, è in realtà una caratteristica utile. – djechlin

+0

Mi piace questa caratteristica ... a volte mi aiuta, ma non riesco a capire perché il codice sopra riportato genererebbe l'avviso di gestione delle risorse - bug? –

risposta

2

Immagino che la conclusione sia questa: si tratta di un bug di Eclipse?

+1

Sembra un bug di Eclipse per me. Forse Eclipse vede che c'è un percorso attraverso 'finally' (quando' stmt' è null) che causa 'stmt.close()' per non essere chiamato. – Alex

-2

Devi essere utilizzando meta di Java 7 con le risorse o di un blocco try-finally:

try(stmt = HibernateSession.instance().connection().prepareStatement("")) { 


} 

Questo avviso verrà generato sui tipi che ereditano da AutoCloseable non sono garantiti per essere chiuso. (O possibile Closeable, non ricordo quale).

Ora che vedo quello che chiedi, scrivi solo codice meno complicato.

Foo f = null; // don't do this, but it's what you're doing 
f = new Foo(); 

è quello che stai facendo, e vi trovarono una delle diverse situazioni in cui in realtà si deve pagare una penale per questo lavoro estranea.

Inoltre il tuo try/finally deve essere pulito. .close() non puoi lanciare, perché stai prendendo?

try { // don't do this 
    stmt.close(); 
} 
catch(SQLException exc) { 

} 

Dovrebbe generare un avviso Eclipse che ti dice che stai prendendo qualcosa che non getta. Potrebbe anche essere un errore di compilazione, non è sicuro, ma sembra che tu possa trarre vantaggio dal giocare con Eclipse> Preferenze> Compilatore e rivedere quali avvisi sono intelligenti. Se non capisci un avvertimento, google e vedere se sarebbe utile a voi, non solo saltare su di esso. (un po 'come hai fatto con questo).

+1

grazie, questo renderebbe il codice molto più chiaro. Vorrei che il mio datore di lavoro adatterebbe jdk 1.7. –

+1

[cosa intendi con _.close() non può throw_?] (Http://docs.oracle.com/javase/6/docs/api/java/sql/Statement.html#close%28%29) –

+1

@OlegMikheev my bad, ho assunto implicitamente che la classe AutoCloseable sia stata progettata correttamente (ho già fatto questo errore in Java prima). – djechlin

-1

Una perdita è possibile se viene generata un'eccezione quando si chiama stmt.close() nel blocco finally.

+1

e come gestite questa perdita? –

-1

Il problema era che nel blocco finally si poteva verificare un'eccezione che impediva la chiusura di stmt.

Una soluzione è che si può sostituire tutto nel blocco finally con:

JDBCUtilities.close(stmt); 

Vedere la docs per JDBCUtilities.close. Come puoi vedere, non verrà generata alcuna eccezione utilizzando questo metodo di utilità in modo da non doverti preoccupare della perdita di risorse. Un ulteriore vantaggio è che il metodo di utilità gestisce la custodia null per stmt e quindi non è necessario codificarla autonomamente.

In realtà, è good practice per utilizzare JDBCUtilities.

+0

Confonderà ancora di più Eclipse, che non può sapere cosa fa 'JDBCUtilities.close (stmt)'. – irreputable

+0

@irreputable Come? Eclipse controlla solo gli errori sintattici, le eccezioni controllate, ecc. Non penso che importi o comprenda la logica aziendale. Nel blocco 'finally' vogliamo chiudere' stmt', che è esattamente ciò che fa 'JDBCUtilities.close'. –

+0

Eclipse non sa che 'JDBCUtilities.close (stmt)' chiama 'stmt.close()' – irreputable

Problemi correlati