2012-01-26 14 views
8

Spesso vedo java SourceCode dove non è consentito un valore null come metodo o costruttore. Una tipica implementazione di questo appare comeHa senso verificare automaticamente null in Java

public void someMethod(Object someObject){ 

    if(someObject == null) throw new NullPointerException() 

    someObject.aMethodCall() 

} 

non vedo alcun senso per me in quel affatto, perché se tento di chiamare un metodo su un nullpointer il NullPointerException è gettato in ogni modo. Vedrei un senso se questo metodo genererebbe un IllegalArgumentException o qualche altra eccezione personalizzata. Qualcuno può chiarire, perché questo controllo sembra avere un senso (come vedo molto spesso sto assumendo, che deve esserci un senso dietro), o perché è assurdo completo

+0

Questo è inutile se il comportamento corretto è quello di puntatore nullo (in realtà è peggio dal momento che il controllo richiede una piccola quantità di tempo). – Jim

+0

I controlli nulli espliciti sono economici quanto i controlli nulli impliciti dopo JIT'ing, quindi non mi preoccuperei delle prestazioni qui. –

+0

Possibile duplicato: http://stackoverflow.com/questions/32280/passing-null-to-a-method Preferisco le asserzioni per il controllo della bontà dei parametri, proprio come le precondizioni utilizzate in Ada. – vulkanino

risposta

9

Il codice che hai postato non ha assolutamente senso. Sembra un caso forte di cargo cult programming. Molto probabilmente, qualcuno ha implementato un test utile per verificare le condizioni preliminari una volta e qualcun altro ha adattato il test per assomigliare a questo.

4

Questo dipende da chi è responsabile di recuperare da questa situazione. Se è il chiamante, lancia un NPE. Se è il metodo chiamato, prova per null e fai tutto ciò che è necessario per risolvere la situazione.

Modifica: Non lanciare un NPE in modo esplicito ma semplicemente farlo esplodere. Ci scusiamo per la formulazione vaga.

+0

Ma nel caso dell'esempio fornito dall'OP, è chiaro che il metodo stesso non si sta ripristinando dall'eccezione ... – cdeszaq

+0

Vero, ma l'ho preso solo come MWE, non come codice reale. –

+0

Lanciare un'eccezione non controllata è una cattiva pratica di programmazione ... –

5

No, non ha molto senso così com'è, ma solo perché il lancio di un NPE non aggiunge alcuna informazione utile.

Si potrebbe fare l'errore più bello da buttare (ad esempio) un IllegalStateException:

if (someObject == null) throw new IllegalStateException("someObject was null"); 

Ma questo non aggiungere un grande valore sia - oltre ad essere specifico su ciò che è nulla (che può essere utile in metodi più complessi)

+0

E la possibile eccezione dovrebbe essere dichiarata nella clausola 'throws' e documentata. –

5

Ovviamente si desidera verificare null. Questa è una pre-condizione per il tuo metodo, parte del suo contratto con i clienti. Se il tuo metodo non può accettare input nulli, devi applicarlo.

La scelta dell'eccezione potrebbe essere migliore. Di solito vado con uno IllegalArgumentException.

Se è la brevità del metodo che ti dà fastidio, devo dire che sono d'accordo. Nessuna nuova informazione lì.

+0

Non credo che "IllegalArgumentException" sia una scelta migliore. 'NPE' è più specifico. Puoi anche consultare l'articolo 60 di Java efficace su di esso. –

+0

Gli darò un'occhiata, ma non so se sono d'accordo. Il messaggio in IAE può chiarire abbastanza. Può anche segnalare altre condizioni (ad esempio, stringa che non può essere né vuota né nulla). La tua interpretazione è molto stretta, ma corretta per questo problema. – duffymo

0

Penso che fare questo tipo di controllo abbia senso se un metodo esegue un'elaborazione che impiega molto tempo o è difficile da annullare prima che attivi effettivamente l'NPE. Nell'esempio dato non penso abbia senso.

D'altra parte: l'uso di asserire o lanciare un'eccezione più specifica come IllegalArgumentException potrebbe avere più senso.

0

In C# esiste un ArgumentNullException. Questa eccezione prende il nome dell'argomento nel costruttore. Quindi il chiamante potrebbe vedere, quale argomento potrebbe essere illiceità NULL. L'IllegalArgumentException è quasi l'equivalente Java di quello.

2

La situazione si descrive può essere utile in uno dei seguenti ipotesi:

1.) Se si deve eseguire alcune operazioni che sono o costose o fare modificare alcune stato globale prima dell'esecuzione someObject.aMethodCall() si può prevenire codice di rollback e spreco di cicli di esecuzione.

2.) Se someObject è memorizzato in una struttura dati, è possibile creare un possibile errore se in un secondo momento i dati vengono recuperati dalla struttura dati. Penso, ricordo alcune classi nel framework di raccolta java, che lanciano piuttosto un NPE piuttosto che consentire un null nella struttura di archiviazione.

+0

Un esempio dalle raccolte Java: Le versioni precedenti di un 'TreeSet' vuoto consentivano l'aggiunta di' null', solo per generare un NPE quando si doveva aggiungere un secondo elemento. La versione corrente di 'TreeSet.add' controlla esplicitamente' null'. –

6

C'è un caso d'angolo in cui qualcosa del genere avrebbe senso. Se non si utilizza someObject, è possibile ricorrere immediatamente al cortocircuito tra l'errore e l'inizio della funzione.

public void someMethod(Object someObject){ 

    if(someObject == null) throw new NullPointerException(); 

    expensiveOperationNotUsingSomeObject(); 

    someObject.aMethodCall(); 
} 
+1

+1 un controllo e un lancio esplicito * possono * essere utili. Pensa fallisci velocemente, fallisci presto. – Qwerky

2

Personalmente la ragione per cui non avevo mai gettare un NullPointerException come parte di un metodo API pubblica è perché rende molto più difficile per il programmatore di distinguere tra un errore di programmazione dalla loro parte e un bug nel mio codice (cioè ho deliberatamente permesso che l'NPE venisse lanciata o no?).

Lanciare un'eccezione diversa rende l'idea molto più chiara e aiuta anche il programmatore a scoprire cosa è più semplice. Quindi andrei con IllegalArgumentException lì.

Se si tratta di un metodo interno? Io userei asserzioni o semplicemente lasciarlo andare in crash. Non ha senso gettare esplicitamente un NPE imo.

Problemi correlati