Si dovrebbe verificare nulla se non si aspetta nulla?

106

La scorsa settimana abbiamo avuto un argomento scottante sulla gestione dei valori null nel livello di servizio della nostra applicazione. La domanda è nel contesto .NET, ma sarà la stessa in Java e in molte altre tecnologie.

La domanda era: dovresti controllare sempre i valori nulli e fare in modo che il tuo codice funzioni, o lasciare che un'eccezione si apra quando un null viene ricevuto in modo imprevisto?

Da un lato, il controllo di null dove non lo si aspetta (ovvero non ha un'interfaccia utente per gestirlo) è, a mio parere, lo stesso che scrivere un blocco try con un catch vuoto. Stai solo nascondendo un errore. L'errore potrebbe essere che qualcosa è cambiato nel codice e null ora è un valore previsto, oppure c'è qualche altro errore e l'ID sbagliato viene passato al metodo.

D'altro canto, il controllo dei valori null può essere una buona abitudine in generale. Inoltre, se c'è un controllo l'applicazione può continuare a funzionare, con solo una piccola parte della funzionalità che non ha alcun effetto. Quindi il cliente potrebbe segnalare un piccolo bug come "impossibile eliminare il commento" invece di un bug molto più grave come "impossibile aprire la pagina X".

Quale pratica segui e quali sono i tuoi argomenti a favore o contro entrambi gli approcci?

Aggiornamento:

Voglio aggiungere alcuni dettagli sul nostro caso particolare. Stavamo recuperando alcuni oggetti dal database e li abbiamo elaborati (diciamo, costruiamo una collezione). Lo sviluppatore che ha scritto il codice non ha previsto che l'oggetto potesse essere nullo, quindi non ha incluso alcun controllo, e quando la pagina è stata caricata c'è stato un errore e l'intera pagina non è stata caricata.

Ovviamente, in questo caso avrebbe dovuto esserci un assegno. Quindi abbiamo discusso se ogni oggetto che viene processato debba essere controllato, anche se non ci si aspetta che manchi, e se l'eventuale elaborazione debba essere interrotta silenziosamente.

Il vantaggio ipotetico sarebbe che la pagina continuerà a funzionare. Pensa ai risultati di una ricerca su Stack Exchange in diversi gruppi (utenti, commenti, domande). Il metodo potrebbe verificare null e interrompere l'elaborazione degli utenti (che a causa di un bug è nullo) ma restituire le sezioni "commenti" e "domande". La pagina continuerà a funzionare eccetto che mancherà la sezione "utenti" (che è un bug). Dovremmo fallire presto e rompere l'intera pagina o continuare a lavorare e aspettare che qualcuno si accorga che manca la sezione "utenti"?

    
posta Stilgar 06.05.2012 - 17:42
fonte

16 risposte

97

La domanda non è tanto se si dovrebbe verificare null o lasciare che il runtime lanci un'eccezione; è come dovresti rispondere a una situazione così inaspettata.

Le tue opzioni, quindi, sono:

  • Genera un'eccezione generica ( NullReferenceException ) e lascia che bolla; se non fai il controllo di null , questo è ciò che accade automaticamente.
  • Genera un'eccezione personalizzata che descrive il problema a un livello superiore; questo può essere ottenuto sia lanciando il controllo null , sia rilevando un NullReferenceException e generando l'eccezione più specifica.
  • Ripristina sostituendo un valore predefinito adatto.

Non esiste una regola generale quale sia la soluzione migliore. Personalmente, direi:

  • L'eccezione generica è migliore se la condizione di errore è un segno di un grave errore nel codice, vale a dire che il valore che è null non dovrebbe mai essere autorizzato ad arrivare in primo luogo. Un'eccezione di questo tipo può quindi sbollire fino a qualsiasi errore di registrazione che hai impostato, in modo che qualcuno venga avvisato e corregge il bug.
  • La soluzione del valore predefinito è buona se fornire un output semi-utile è più importante della correttezza, come un browser Web che accetta HTML tecnicamente scorretto e fa il possibile per renderlo sensibilmente.
  • Altrimenti, andrei con l'eccezione specifica e la gestirò in un posto adatto.
risposta data 06.05.2012 - 20:58
fonte
56

IMHO tenta di gestire valori nulli che non ti aspetti porta a un codice troppo complicato. Se non ti aspetti nulla, rendi chiaro lanciando ArgumentNullException . Mi sento davvero frustrato quando le persone controllano se il valore è nullo e poi provano a scrivere del codice che non ha alcun senso. Lo stesso vale per l'utilizzo di SingleOrDefault (o anche peggio per la raccolta) quando qualcuno si aspetta davvero Single e molti altri casi in cui le persone hanno paura (non so davvero cosa) di indicare chiaramente la loro logica.

    
risposta data 06.05.2012 - 17:58
fonte
34

L'abitudine di cercare null nella mia esperienza proviene da precedenti sviluppatori C o C ++, in quelle lingue hai una buona possibilità di nascondere un grave errore quando non controlla NULL . Come sapete, in Java o in C # le cose sono diverse, l'utilizzo di un riferimento null senza controllo per null causerà un'eccezione, quindi l'errore non sarà nascosto segretamente finché non lo ignorerete dal lato chiamante. Pertanto, nella maggior parte dei casi, il controllo esplicito di null non ha molto senso e rende più complicato il codice più del necessario. Ecco perché non consideri che il controllo nullo sia una buona abitudine in quelle lingue (almeno, non in generale).

Naturalmente, ci sono delle eccezioni da quella regola, eccone quelle che mi viene in mente:

  • si desidera un messaggio di errore migliore, leggibile dall'uomo, che informa l'utente in quale parte del programma si è verificato il riferimento null errato. Quindi il tuo test per null genera solo un'eccezione diversa, con un testo di errore diverso. Ovviamente, nessun errore verrà mascherato in questo modo.

  • vuoi rendere il tuo programma "fallire più presto". Ad esempio, si desidera verificare un valore nullo di un parametro del costruttore, in cui il riferimento all'oggetto sarebbe altrimenti memorizzato in una variabile membro e utilizzato successivamente.

  • puoi gestire la situazione di un ref null in modo sicuro, senza il rischio di errori successivi e senza mascherare un grave errore.

  • vuoi un tipo completamente diverso di segnalazione degli errori (ad esempio, restituendo un codice di errore) nel tuo contesto attuale

risposta data 06.05.2012 - 18:12
fonte
15

Utilizza asserzioni per testare e indicare pre / post-condizioni e invarianti per il tuo codice.

Rende molto più facile capire cosa si aspetta il codice e cosa ci si può aspettare che maneggi.

Un assert, IMO, è un assegno adatto perché è:

  • efficiente (di solito non utilizzato nella versione),
  • breve (di solito una singola riga) e
  • clear (precondizione violata, questo è un errore di programmazione).

Penso che il codice di auto-documentazione sia importante, quindi avere un controllo è buono. La programmazione difensiva, a prova di errore, semplifica la manutenzione, che è solitamente la maggior parte del tempo trascorso.

Aggiorna

Wrt your elaboration. Di solito è bene dare all'utente finale un'applicazione che funziona bene sotto bug, cioè mostra il più possibile. La robustezza è buona, perché il cielo sa solo cosa si romperà in un momento critico.

Tuttavia, gli sviluppatori e amp; i tester devono essere a conoscenza dei bug al più presto, quindi probabilmente si desidera un framework di registrazione con un hook che possa visualizzare un avviso all'utente che si è verificato un problema. L'avviso dovrebbe probabilmente essere mostrato a tutti gli utenti, ma può probabilmente essere adattato in modo diverso a seconda dell'ambiente di runtime.

    
risposta data 06.05.2012 - 21:51
fonte
7

Fallisci presto, fallisci spesso. null è uno dei migliori valori imprevisti che puoi ottenere, perché puoi fallire rapidamente non appena tenti di usarlo. Altri valori inaspettati non sono così facili da rilevare. Poiché null fallisce automaticamente per te ogni volta che provi ad usarlo, direi che non richiede un controllo esplicito.

    
risposta data 06.05.2012 - 17:57
fonte
6
  • Il controllo di null dovrebbe essere la tua seconda natura

  • La tua API verrà utilizzata da altre persone e le loro aspettative saranno probabilmente diverse dalle tue

  • I test completi dell'unità evidenziano normalmente la necessità di un controllo di riferimento null

  • Il controllo dei valori null non implica istruzioni condizionali. Se ti preoccupi che il controllo nullo renda il tuo codice meno leggibile, potresti prendere in considerazione i contratti del codice .NET.

  • Considera l'installazione di ReSharper (o simili) per cercare nel codice gli assegni di riferimento null mancanti

risposta data 06.05.2012 - 21:47
fonte
4

Considererei la domanda dal punto di vista della semantica, cioè mi chiedo che cosa rappresenti un puntatore NULL o un argomento di riferimento nullo.

Se una funzione o un metodo foo () ha un argomento x di tipo T, x può essere obbligatorio o facoltativo .

In C ++ puoi passare un argomento obbligatorio come

  • Un valore, ad es. void foo (T x)
  • Un riferimento, ad es. void foo (T & x).

In entrambi i casi non si ha il problema di controllare un puntatore NULL. Quindi, in molti casi, non è necessario un controllo del puntatore nullo affatto per gli argomenti obbligatori.

Se passi un argomento facoltativo , puoi utilizzare un puntatore e utilizzare il valore NULL per indicare che non è stato fornito alcun valore:

void foo(T* x)

Un'alternativa è usare un puntatore intelligente come

void foo(shared_ptr<T> x)

In questo caso, probabilmente vuoi controllare il puntatore nel codice, perché fa una differenza per il metodo foo () se x contiene un valore o nessun valore.

Il terzo e ultimo caso è che utilizzi un puntatore per un obbligatorio discussione. In questo caso, chiamare foo (x) con x == NULL è un errore e devi decidere come gestire questo (lo stesso come con un indice out-of-bounds o qualsiasi input non valido):

  1. Nessun controllo: se c'è un bug lascia che si blocca e spero che questo bug appaia abbastanza presto (durante i test). In caso contrario (se non si riesce a fallire abbastanza presto), sperare che non venga visualizzato in un sistema di produzione perché l'esperienza utente sarà che vedono l'arresto anomalo dell'applicazione.
  2. Controlla tutti gli argomenti all'inizio del metodo e segnala argomenti NULL non validi, ad es. lanciare un'eccezione da foo () e lasciare che sia gestita da un altro metodo. Probabilmente la cosa migliore da fare è mostrare all'utente una finestra di dialogo che dice che l'applicazione ha riscontrato un errore interno e sta per essere chiusa.

A parte un modo migliore di fallire (dando all'utente maggiori informazioni), un vantaggio del secondo approccio è che è più probabile che il bug venga trovato: il programma fallirà ogni volta che il metodo viene chiamato con il torto argomenti considerando che con l'approccio 1 il bug apparirà solo se viene eseguita un'istruzione che dereferenzia il puntatore (ad esempio se viene inserito il ramo destro di un'istruzione if). Quindi l'approccio 2 offre una forma più strong di "fallire presto".

In Java hai meno scelte perché tutti gli oggetti vengono passati usando riferimenti che possono sempre essere nulli. Di nuovo, se il null rappresenta un valore NONE di un argomento facoltativo, allora il controllo di null sarà (probabilmente) parte della logica di implementazione.

Se il null è un input non valido, allora si ha un errore e applicherei considerazioni simili come nel caso dei puntatori C ++. Poiché in Java è possibile rilevare eccezioni di puntatori nulli, l'approccio 1 sopra equivale all'approccio 2 se method foo () dereferenzia tutti gli argomenti di input in tutti i percorsi di esecuzione (che probabilmente si verifica molto spesso per metodi di piccole dimensioni).

Riassumendo

  • Sia in C ++ che in Java, controllando se argomenti facoltativi sono nulli fa parte della logica del programma.
  • In C ++, verificherei sempre argomenti obbligatori per garantire che venga generata un'eccezione appropriata in modo che il programma possa gestirla in modo robusto.
  • In Java (o C #), verificherei argomenti obbligatori se ci sono percorsi di esecuzione che non verranno lanciati per avere una forma più strong di "fail iniziale".

Modifica

Grazie a Stilgar per maggiori dettagli.

Nel tuo caso sembra che tu abbia null come risultato di un metodo. Ancora una volta, penso che prima dovresti chiarire (e sistemare) la semantica dei tuoi metodi puoi prendere una decisione.

Quindi hai metodo metodo di chiamata m1 () m2 () e m2 () restituisce un riferimento (in Java) o un puntatore (in C ++) su qualche oggetto.

Qual è la semantica di m2 ()? M2 () dovrebbe sempre restituire un risultato non nullo? In questo caso, un risultato nullo è un errore interno (in m2 ()). Se si controlla il valore restituito in m1 () si può avere una gestione degli errori più robusta. Se non lo fai, probabilmente avrai un'eccezione, prima o poi. Forse no. Spero che l'eccezione venga generata durante i test e non dopo la distribuzione. Domanda : se m2 () non dovrebbe mai restituire null, perché restituisce null? Forse dovrebbe invece lanciare un'eccezione? m2 () è probabilmente bacato.

L'alternativa è che restituire null fa parte della semantica del metodo m2 (), cioè ha un risultato facoltativo, che dovrebbe essere documentato nella documentazione Javadoc del metodo. In questo caso è OK avere un valore nullo. Il metodo m1 () dovrebbe controllarlo come qualsiasi altro valore: non c'è nessun errore qui ma probabilmente controllare se il risultato è nullo è solo parte della logica del programma.

    
risposta data 06.05.2012 - 19:51
fonte
3

Il mio approccio generale è di non testare mai una condizione di errore che non sai come gestire . Quindi la domanda a cui è necessario rispondere in ogni istanza specifica diventa: puoi fare qualcosa di ragionevole in presenza del valore null imprevisto?

Se puoi continuare tranquillamente sostituendo un altro valore (una collezione vuota, per esempio, o un valore o un'istanza predefiniti), allora fallo con tutti i mezzi. @ L'esempio di Shahbaz di World of Warcraft di sostituire un'immagine per un'altra cade in quella categoria; l'immagine stessa è probabilmente solo decorazione e non ha impatto funzionale . (In una build di debug, userei un colore urlante per attirare l'attenzione sul fatto che è avvenuta la sostituzione, ma ciò dipende molto dalla natura dell'applicazione.) Registra i dettagli sull'errore, però, così sai che sta accadendo; altrimenti, nasconderai un errore che probabilmente vorresti sapere. Nasconderlo dall'utente è una cosa (anche in questo caso, supponendo che l'elaborazione possa continuare in sicurezza); nasconderlo dallo sviluppatore è un altro.

Se non puoi continuare tranquillamente in presenza di un valore nullo, fallisci con un errore ragionevole; in generale, preferisco fallire il prima possibile quando è ovvio che l'operazione non può avere successo, il che implica il controllo delle precondizioni. Ci sono momenti in cui non vuoi fallire immediatamente, ma rimanda il fallimento il più a lungo possibile; questa considerazione arriva ad esempio nelle applicazioni relative alla crittografia, in cui gli attacchi di canale laterale potrebbero altrimenti divulgare informazioni che non si desidera conoscere. Alla fine, lascia che l'errore diventi un errore in un gestore di errori generale, che a sua volta registra i dettagli rilevanti e visualizza un messaggio di errore piacevole (per quanto piacevole possa essere) all'utente.

Vale anche la pena notare che la risposta corretta potrebbe benissimo differire tra test / build QA / debug e build di produzione / rilascio. Nelle build di debug, vorrei fallire precocemente e con messaggi di errore molto dettagliati, per rendere assolutamente ovvio che c'è un problema e consentire a un post-mortem di determinare che cosa è necessario fare per risolverlo. Le build di produzione, di fronte agli errori recuperabili in modo sicuro , dovrebbero probabilmente favorire il recupero.

    
risposta data 07.05.2012 - 13:31
fonte
2

Certo NULL non è atteso , ma ci sono sempre bug!

Credo che dovrebbe verificare la presenza di NULL indipendentemente dal fatto che non te lo aspetti. Lascia che ti dia degli esempi (anche se non sono in Java).

  • In World of Warcraft, a causa di un bug, l'immagine di uno degli sviluppatori è apparsa su un cubo per molti oggetti. Immagina che se il motore grafico non avesse aspettarsi NULL puntatori, ci sarebbe stato un crash, mentre si sarebbe trasformato in un'esperienza non così fatale (e persino divertente) per l'utente. Il minimo è che non avresti perso inaspettatamente la tua connessione o nessuno dei tuoi punti di salvataggio.

    Questo è un esempio in cui il controllo di NULL ha impedito un arresto anomalo e il caso è stato gestito in modo silenzioso.

  • Immagina un programma di sportelli bancari. L'interfaccia esegue alcuni controlli e invia i dati di input a una parte sottostante per eseguire i trasferimenti di denaro. Se la parte centrale si aspetta di non ricevere NULL , un bug nell'interfaccia può causare un problema nella transazione, probabilmente un po 'di denaro nel mezzo perdersi (o peggio, duplicato).

    Con "un problema" intendo un arresto anomalo (come in un arresto incidente (ad esempio il programma è scritto in C ++), non un'eccezione di puntatore nullo). In questo caso, la transazione deve essere ripristinata se viene rilevato NULL (che ovviamente non sarebbe possibile se non si controllassero le variabili con NULL!)

Sono sicuro che ti viene l'idea.

Il controllo della validità degli argomenti per le tue funzioni non ingombra il tuo codice, poiché si tratta di un paio di controlli nella parte superiore della tua funzione (non distribuiti nel mezzo) e aumenta notevolmente la robustezza.

Se devi scegliere tra "il programma dice all'utente che ha fallito e si arresta con garbo o ripristina uno stato coerente, possibilmente creando un log degli errori" e "Violazione di accesso", non sceglieresti il primo ? Ciò significa che ogni funzione dovrebbe essere preparata per essere chiamata da un codice bacato piuttosto che aspettarsi tutto è corretto, semplicemente perché esistono sempre errori.

    
risposta data 07.05.2012 - 02:00
fonte
2

Come indicato dalle altre risposte Se non ti aspetti NULL , rendi chiaro lanciando ArgumentNullException . A mio avviso, quando esegui il debug del progetto ti aiuta a scoprire prima i guasti nella logica del tuo programma.

Quindi rilascerai il tuo software, se ripristini quei controlli di NullRefrences , non ti perdi nulla sulla logica del tuo software, ma fai solo il doppio del fatto che non verrà visualizzato un bug grave.

Un altro punto è che se il controllo NULL è sui parametri di una funzione, allora puoi decidere se la funzione è il posto giusto per farlo o meno; in caso contrario, trovare tutti i riferimenti alla funzione e quindi prima di passare un parametro alla funzione rivedere gli scenari probabili che potrebbero portare a un riferimento nullo.

    
risposta data 02.02.2015 - 19:40
fonte
1

Ogni null nel tuo sistema è una bomba ad orologeria che attende di essere scoperta. Verifica null ai limiti in cui il tuo codice interagisce con il codice che non controlli e proibisci null all'interno del tuo codice. Questo ti libera dal problema senza ingenuamente fidarsi del codice straniero. Utilizza invece le eccezioni o qualche tipo di Maybe / Nothing type.

    
risposta data 29.01.2014 - 21:33
fonte
0

Mentre un'eccezione del puntatore nullo verrà lanciata, verrà spesso lanciata lontano dal punto in cui hai ottenuto il puntatore nullo. Fai un favore a te stesso e abbrevia il tempo necessario per correggere il bug almeno registrando il fatto che crei un puntatore nullo il prima possibile.

Anche se non sai cosa fare ora, la registrazione dell'evento ti farà risparmiare tempo dopo. E forse il tizio che riceve il biglietto sarà in grado di utilizzare il tempo risparmiato per capire la risposta corretta allora.

    
risposta data 07.05.2012 - 15:15
fonte
-1

Poiché Fail early, fail fast come dichiarato da @DeadMG (@empi) non è pssible perché l'applicazione web deve funzionare bene sotto bug dovresti applicare la regola

nessuna cattura di eccezioni senza registrazione

così come gli sviluppatori sono consapevoli dei potenziali problemi controllando i registri.

Se si utilizza un framework di registrazione come log4net o log4j è possibile impostare un output di registrazione speciale aggiuntivo (noto anche come appender) che invia messaggi di errore e fatalerrors. quindi rimani informato .

[update]

se l'utente finale della pagina non deve essere a conoscenza dell'errore è possibile impostare un appender  ti mando errori e fatalerror tieni informato.

se è giusto che l'utente finale della pagina visualizzi messaggi di errore criptici, puoi configurare un appender che inserisce il log degli errori per il page processing alla fine della pagina.

Indipendentemente dal modo in cui utilizzi la registrazione se elimini l'eccezione, il programma continua con dati che hanno senso e la deglutizione non è più silenziosa.

    
risposta data 07.05.2012 - 09:38
fonte
-1

Ci sono già buone risposte a questa domanda, potrebbe essere un'aggiunta a loro: preferisco le asserzioni nel mio codice. Se il tuo codice può funzionare solo con oggetti validi, ma nut con null, devi affermare sul valore null.

Le asserzioni in questo tipo di situazione consentirebbero a qualsiasi unità e / o test di integrazione di fallire con il messaggio esatto, in modo da poter risolvere il problema abbastanza velocemente prima della produzione. Se un tale errore scivola attraverso i test e va in produzione (dove le asserzioni dovrebbero essere disattivate) riceverai NpEx, e un bug grave, ma è meglio, di qualche bug minore che è molto più confuso e spuntando da qualche altra parte nel codice, e sarebbe più costoso da risolvere.

Ancora di più se qualcuno deve lavorare con le tue affermazioni sul codice gli parla delle tue supposizioni fatte durante la progettazione / scrittura del tuo codice (in questo caso: Hey amico, questo oggetto deve essere presentato!), il che rende più facile la manutenzione.

    
risposta data 11.05.2012 - 08:47
fonte
-1

Normalmente controllo i valori nulli ma "gestisco" i null inattesi generando un'eccezione che fornisce un po 'più di dettaglio su dove si è verificato il null.

Modifica: se ottieni un valore nullo quando non ti aspetti che una cosa sia sbagliata, il programma dovrebbe morire.

    
risposta data 11.05.2012 - 19:53
fonte
-1

Dipende dall'implementazione linguistica delle eccezioni. Le eccezioni consentono di intervenire per prevenire danni ai dati o rilasciare risorse in modo pulito nel caso in cui il sistema entri in uno stato o una condizione inattesa. Questo è diverso dalla gestione degli errori che sono le condizioni che puoi anticipare. La mia filosofia è che si dovrebbe avere il minor numero possibile di gestione delle eccezioni. È un rumore. Il tuo metodo può fare qualcosa di ragionevole gestendo l'eccezione? Può recuperare? Può riparare o prevenire ulteriori danni? Se stai solo andando a prendere l'eccezione e poi tornare dal metodo o fallire in qualche altro modo innocuo allora non c'era davvero nessun punto nel catturare l'eccezione. Avresti aggiunto solo rumore e complessità al tuo metodo e potresti nascondere la fonte di un errore nel tuo progetto. In questo caso lascerei scoppiare il difetto e venissi catturato da un anello esterno. Se si può fare qualcosa come riparare un oggetto o contrassegnarlo come corrotto o rilasciare alcune risorse critiche come un file di blocco o chiudendo un socket in modo pulito, questo è un buon uso delle eccezioni. Se si prevede che il valore NULL venga visualizzato frequentemente come caso limite valido, è necessario gestirlo nel normale flusso logico con le istruzioni if-the-else o switch-case o qualsiasi altra cosa, non con una gestione delle eccezioni. Ad esempio, un campo disabilitato in un modulo può essere impostato su NULL, che è diverso da una stringa vuota che rappresenta un campo lasciato vuoto. Questa è un'area in cui è necessario utilizzare il buon senso e il buon senso. Non ho mai sentito di buone regole pratiche su come affrontare questo problema in ogni situazione.

Java non riesce nella sua implementazione della gestione delle eccezioni con "eccezioni controllate" dove ogni possibile eccezione che potrebbe essere generata da oggetti usati in un metodo deve essere rilevata o dichiarata nella clausola "throws" del metodo. È l'opposto di C ++ e Python in cui è possibile scegliere di gestire le eccezioni come meglio credi. In Java, se si modifica il corpo di un metodo per includere una chiamata che potrebbe generare un'eccezione, si deve scegliere di aggiungere una gestione esplicita per un'eccezione che potrebbe non interessare, aggiungendo così rumore e complessità al codice, oppure è necessario aggiungi quell'eccezione alla clausola "getta" del metodo che stai modificando, che non solo aggiunge rumore e confusione ma modifica la firma del tuo metodo. È quindi necessario immettere un codice di modifica ovunque il metodo venga utilizzato per gestire la nuova eccezione, il metodo ora può aumentare o aggiungere l'eccezione alla clausola "throws" di tali metodi, innescando quindi un effetto domino delle modifiche al codice. Il "Catch or Specify Requirement" deve essere uno degli aspetti più fastidiosi di Java. L'eccezione di eccezione per RuntimeExceptions e la razionalizzazione ufficiale di Java per questo errore di progettazione è lame.

L'ultimo paragrafo aveva poco a che fare con la risposta alla tua domanda. Odio Java.

- Noah

    
risposta data 23.05.2015 - 16:18
fonte

Leggi altre domande sui tag