E 'un approccio accettabile mettere try try catch ovunque si verifichi un'eccezione del puntatore nullo?

7

Esistono casi in cui i riferimenti a oggetti, campi, variabili ecc. possono essere nulli e potrebbe verificarsi una possibile occorrenza dell'eccezione Null Pointer in quel punto.

Is è una soluzione permanente per mettere questi blocchi di codice che si aspettano che l'eccezione Ponter Null venga inserita in un blocco catch try?

    
posta Nigel Thomas 15.02.2013 - 11:26
fonte

8 risposte

6

Se utilizzi un codice di terze parti che restituisce null , è molto meglio controllare il valore restituito.

ThirdPartyValue thirdPartyValue = thirdParty.getValue();
if (null == thirdPartyValue) {
    ...
}

Modifica: Java 8 è fuori! Ora dovrebbe essere

Optional<ThirdPartyValue> thirdPartyValue = Optional.ofNullable(thirdParty.getValue());

Un NullPointerException è insidioso e fuorviante, perché significa che hai un errore da qualche altra parte, dove una variabile è stata impostata su null senza che tu te lo aspetti.

Ripeto, il bug non è dove è stato lanciato NullPointerException , il bug è precedente nel tuo codice , dove una variabile è stata impostata a null senza che tu te lo aspetti.

Catching NullPointerException significa che stai nascondendo o scusando il bug effettivo.

Nel tuo codice, è molto meglio eliminare null ogni volta che è possibile, e per questo anche variabili mutabili.

Se ricevi un'eccezione, non prenderla e restituisci null , invece esegui il wrapping e rilancia l'eccezione.

Se hai un metodo che a volte non dovrebbe restituire un valore, puoi restituire un Collection vuoto o un Opzionale , che è nuovo in Java 8.

Se non imposti mai una variabile su null non puoi mai avere un null imprevisto.

Non consentire parametri null :

public void method(A param1, B param2, C param3) {
    requireNonNull(param1, param2, param3);
    ...
}

public static void requireNonNull(Object... parameters) {
    Stream.of(parameters).forEach(Objects::requireNonNull);
}

Evita di creare variabili "risultato" temporaneamente null :

Invece di:

public Result method() {
    Result result = null;    // <- this smells
    try {
        result = ...;
    } catch (SomeException e) {
        LOGGER.log(Level.WARNING, "Exception "+e.getMessage(), e);
    }
    return result;
}

dovresti:

public Result method() {
    try {
        return ...;
    } catch (SomeException e) {
        throw new MyPossiblyRuntimeException(e);
    }
}

Prima o poi inizierai a vedere l'utilizzo di null (e variabili mutabili) come odore di codice.

Sono sicuro che puoi inventare altri modi intelligenti per evitare null , essere creativi!

tl; dr : il NullPointerException non dovrebbe mai essere lanciato in primo luogo, quindi non prenderlo, perché ciò significa che stai nascondendo il bug effettivo.

    
risposta data 15.02.2013 - 17:39
fonte
22

Per quanto riguarda il tuo commento:

I mean instead of showing a Stack trace error how can we make the user more understandable about the Null pointer that happened.

L'utente non sa né si preoccupa di cosa sia un puntatore Null. Se si verifica una NullPointerException, si tratta di un bug nel codice. Dovrebbe essere catturato e registrato dal gestore globale delle eccezioni, quindi il bug dovrebbe essere corretto e dovrebbe essere spedito un aggiornamento.

( fai usi un gestore globale di eccezioni catch-all che registra l'eccezione, si scusa con l'utente, termina l'applicazione e ordina all'utente come inviare lo stack trace a te, giusto? In caso contrario, potrebbe essere un buon momento per iniziare.

    
risposta data 15.02.2013 - 11:44
fonte
11

Dipende dal blocco di codice, ma sì, in molti casi try-catch è una buona soluzione per gestire un numero di bug relativi al puntatore nullo che non si è pronti ad affrontare individualmente. Devi soddisfare due condizioni per rendere le eccezioni utili:

  1. Non località di gestione : non utilizzare try-tranne quando un semplice if sarebbe sufficiente. Utilizza try-tranne quando l'errore si verifica lontano dal luogo in cui viene gestito, ad es. in profondità nello stack di chiamate o all'interno di un grande blocco di codice.
  2. Gestione degli errori utile : fa più del gestore delle eccezioni predefinito. Annullare logicamente un'operazione con un messaggio di errore utile . Gestisci l'eccezione in un punto in cui puoi effettivamente prendere una decisione informata sul processo di alto livello. In un'applicazione MVC GUI, il Controller è spesso un buon posto. In nessun caso gestire l'eccezione vicino al punto di generazione, registrarlo e dimenticarlo - è utile solo per i log.
risposta data 15.02.2013 - 11:44
fonte
4

No. Se qualcuno passa un puntatore nullo dove non te lo aspettavi, allora questo è un bug. Falli trattare con l'eccezione: è il loro problema.

    
risposta data 15.02.2013 - 11:28
fonte
1

Non ha senso inserire la gestione delle eccezioni in cui non si gestiscono realmente eccezioni. È un sacco di codice extra e amp; rende difficile seguire il programma. Se si desidera mostrare agli utenti errori "amichevoli", è sufficiente disporre di un gestore di eccezioni di primo livello.

    
risposta data 15.02.2013 - 16:01
fonte
0

L'uso di un blocco try-catch ogni volta renderà il tuo codice inutilmente complicato e meno leggibile. Inoltre, se il tuo codice è pensato a fondo, di solito non dovrebbero puntatori null "imprevedibili".

Nella maggior parte dei casi è sufficiente un controllo se alcune variabili sono nulle. Se necessario, è possibile registrare un messaggio se una variabile è nullo.

    
risposta data 15.02.2013 - 11:37
fonte
0

La vera risposta è che dipende dal dominio dell'applicazione.

È più importante che funzioni esattamente con le specifiche (calcolatrice di copertura finanziaria che fornisce risultati errati) o è più importante che rimanga in piedi a prescindere da quale (sito di e-commerce con un'intestazione in alto)?

In alcune aziende un risultato leggermente errato è peggio di nessun risultato. In questi casi, si desidera eseguire il fail veloce ed esplicito quando accade qualcosa di inaspettato e strano in modo che le persone che ispezionano i log possano svolgere il loro lavoro e la causa principale possa essere trovata e risolta.

Nel frattempo se questa non è la tua situazione e l'obiettivo è il massimo tempo di attività, la risposta di thiton è la strada da percorrere.

    
risposta data 15.02.2013 - 14:43
fonte
0

Is is a permanent solution to put these code blocks which expect Null ponter exception to be put in a try catch block?

Questo suona come l'anti-pattern dell'uso di eccezioni per il controllo del flusso (in particolare, eccezioni del puntatore nullo).

Quindi, no, non è una buona pratica di programmazione farlo. Quando possibile, il codice dovrebbe evitare di sollevare un'eccezione di puntatore nullo e utilizzare invece l'interruzione / restituzione per il flusso di controllo.

L'unica eccezione è quando si interfaccia con una libreria che genera un'eccezione di puntatore nullo non deterministica per segnalare un certo tipo di errore. In questo caso, la libreria è un esempio di anti-pattern, e l'unica cosa che puoi fare è catturare l'eccezione, ovviamente.

    
risposta data 01.04.2015 - 11:02
fonte

Leggi altre domande sui tag