È vantaggioso lanciare un'eccezione IOException come UncheckedIOException al fine di prevenire NullPointerException?

0

Non si utilizza UncheckedIOException, NullPointerException possibile

public void callerMethod() {
    Object result = ioMethod();

    // call instance method of result
}

public Object ioMethod() {
    try {
        // IO Stuff
        return new Object();
    }
    catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

Utilizzo di UncheckedIOException, NullPointerException non è possibile

public void callerMethod() {
    Object result = ioMethod();

    // call instance method of result
}

public Object ioMethod() {
    try {
        // IO Stuff
        return new Object();
    }
    catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}

In entrambi i casi, null non è un tipo di risposta valido di ioMethod (si verificherebbe solo a causa di un IOException ). Devo anticipare l'eccezione non controllata ( UncheckedIOException ) per evitare un'eccezione non controllata in un secondo momento ( NullPointerException ) o non provare a impedire il NullPointerException ?

    
posta Mar Dev 04.11.2018 - 19:15
fonte

2 risposte

2

In both cases, null is not a valid response type of ioMethod (it would only occur due to an IOException).

Mi permetto di dissentire.

Nel primo caso hai recuperato dall'eccezione. Quello che ritorni ora deve essere una risposta valida o stai violando il tuo contratto. Restituire null è fastidioso, ma se è quello che si restituisce è un ritorno valido.

Questo non significa che dopo il recupero devi restituire null o evitare di tornare affatto. Il tuo metodo restituisce semplicemente 1 o 0 cose. Abbiamo qualcosa per questo.

public void callerMethod() {
    List result = ioMethod(); 

    // call instance method of result
    for (o : result) {
        o.toString(); //No risk of null pointer exception
    }
}

public Object ioMethod() {
    List result = new ArrayList();

    try {
        // IO Stuff
        result.add( new Object() );
    }
    catch (IOException e) {
        e.printStackTrace();
    }

    return result;
}

Le raccolte funzionano molto bene quando non sei sicuro di quante cose hai intenzione di avere. Se ritieni che sia troppo strano da guardare, allora sentiti libero di conoscere Facoltativo . Ti consente di fare praticamente la stessa cosa. Il vantaggio è che renderà più ovvio il 2 e il massimo non saranno coinvolti.

Le persone diventano strane a proposito di 0 e 1. Il nulla è ancora un concetto difficile e 1 sembra che debba essere speciale. Ma ciò non significa che devi raggiungere null o evitare di tornare.

Se insisti su null un semplice if (result != null) guardia si prende cura di esso. È fastidioso, ma questo è l'accordo con null .

Puoi anche restituire un oggetto nullo che silenziosamente non farà nulla quando gli verrà chiesto di fare qualcosa. È un po 'di lavoro per farlo, ma ora il chiamante non deve cambiare. È senza dubbio il mio modello di design preferito. Se hai mai usato la stringa vuota ("") ne hai già usato una forma.

Per quanto riguarda il tuo secondo caso:

Il punto di lancio delle eccezioni è quello di ripristinare il sistema riportando il sistema in uno stato buono noto o arrestando il sistema perché non è possibile tornare a uno stato buono noto.

Scegliere quale eccezione lanciare consiste nel trovare il codice di ripristino corretto per tornare a uno stato buono noto.

Quindi lasciarlo come NullPointerException va bene, e cambiarlo va bene fintanto che assicura che l'eccezione venga ripristinata correttamente.

Il problema è così dannatamente molte cose possono causare un NullPointerException . Una volta che gli permetti di accadere (piuttosto che evitarlo) è abbastanza difficile sapere cosa lo ha causato esattamente. Il che significa che il tuo try deve essere molto piccolo e chiamare un codice molto silenzioso o stai solo indovinando cosa ti ha lanciato.

Quindi, se stai per rilanciare, assicurati di sapere cosa hai catturato. Detto questo e sto bene con te evitando le assurdità delle eccezioni controllate fintanto che il tuo codice base è coerente al riguardo.

    
risposta data 04.11.2018 - 22:22
fonte
4

TL; DR Un metodo che fallisce (non adempie al suo contratto) dovrebbe assicurarsi che il suo chiamante ottenga un'eccezione, sia creando uno nuovo sia lasciando che qualche eccezione originale si propaghi.

Sì, il lancio di un UncheckedIOException è vantaggioso. Non tanto per prevenire più tardi NullPointerExceptions , ma come il modo preferito di dire al tuo chiamante circa l'errore ioMethod() .

Se un po 'di methodA() chiama ioMethod() , lo fa per un motivo, e molto probabilmente non può adempiere al suo lavoro con successo di ioMethod() . Quindi, ricevere un'eccezione da ioMethod() fa sì che anche methodA() fallisca con la stessa eccezione, senza la necessità di scrivere una riga di codice specifica per la gestione degli errori in methodA() .

Se si sceglie di restituire null, si forza methodA() per racchiudere la chiamata di ioMethod() in un condizionale, e tutti sappiamo dai cattivi vecchi giorni senza eccezioni che i programmatori sono pigri e tendono a dimenticare la gestione degli errori.

Restituire null è una soluzione valida se può essere vista come risultato valido del metodo anziché come errore. E poi il suo nome dovrebbe indicare chiaramente che (ad esempio un nome come tryToRead() , per ricordare al "programmatore pigro" di occuparsi del valore nullo.

    
risposta data 04.11.2018 - 22:22
fonte

Leggi altre domande sui tag