Restituire null design errato? [chiuso]


127

Ho sentito alcune voci affermare che il controllo di un valore null restituito dai metodi non è corretto. Mi piacerebbe sentire alcune ragioni per questo.

pseudocodice:

variable x = object.method()
if (x is null) do something

13
Elaborato: dove sono queste persone che dicono che è male? Link?
jcollum,

2
Se il metodo è qualcosa su cui hai il controllo, puoi avere dei test unitari per assicurarti che non ritorni mai null, altrimenti non vedo perché sarebbe una cattiva pratica controllare se è nullo, dopo quella chiamata; forse è una cattiva pratica su quel metodo restituire null, ma devi proteggere il tuo codice
BlackTigerX

9
Sollevare eccezioni solo perché non ci sono dati da restituire è incredibilmente fastidioso. Il normale flusso di programma non dovrebbe generare eccezioni.
Thorarin,

4
@ David: Questo è quello che ho detto davvero. Se un metodo deve restituire dati, ma non è presente, significa che anche qualcosa è andato storto. Non è un normale flusso di programmi :)
Thorarin,

2
@Thorarin: il flusso di programma "normale" è un concetto abbastanza estensibile: non è davvero una base solida per un argomento.
Tomislav Nakic-Alfirevic,

Risposte:


206

La logica alla base della non restituzione di null è che non è necessario verificarlo e quindi il codice non deve seguire un percorso diverso in base al valore restituito. Potresti voler controllare il modello di oggetti nulli che fornisce ulteriori informazioni al riguardo.

Ad esempio, se dovessi definire un metodo in Java che ha restituito una raccolta, in genere preferirei restituire una raccolta vuota (cioè Collections.emptyList()) piuttosto che nulla in quanto significa che il mio codice client è più pulito; per esempio

Collection<? extends Item> c = getItems(); // Will never return null.

for (Item item : c) { // Will not enter the loop if c is empty.
  // Process item.
}

... che è più pulito di:

Collection<? extends Item> c = getItems(); // Could potentially return null.

// Two possible code paths now so harder to test.
if (c != null) {
  for (Item item : c) {
    // Process item.
  }
}

6
Sì, molto meglio che restituire null e sperare che il cliente si ricordi di occuparsi del caso.
djna,

10
Concordo felicemente sul fatto che restituire null sia folle quando viene utilizzato come sostituto di contenitori vuoti (o stringhe). Questo non è il caso comune però.
MSalters,

2
+1 per il modello di oggetti nulli anche per me. Inoltre, quando in realtà voglio restituire null, ho chiamato il metodo come getCustomerOrNull () per renderlo esplicito. Penso che un metodo sia chiamato bene quando il lettore non vuole guardare l'implementazione.
Mike Valenty,

4
Il commento "// Due possibili percorsi di codice ora" non è corretto; hai due percorsi di codice in entrambi i modi. Tuttavia, con l'oggetto Collection null nel primo esempio, il percorso del codice "null" è più breve. Tuttavia, hai ancora due percorsi e devi ancora testare due percorsi.
Frerich Raabe,

1
@MSalters - probabilmente ogni variabile nei linguaggi OO nullè un "contenitore", che contiene zero o un puntatore agli oggetti. (Questo è certamente il modo in cui è esplicitamente modellato da Haskell Maybein quei casi, ed è tanto meglio per farlo.)
Andrzej Doyle,

71

Ecco il motivo.

In Clean Code di Robert Martin scrive che restituire null è un cattivo design quando si può invece restituire, diciamo, array vuoto. Poiché il risultato atteso è un array, perché no? Ti consentirà di ripetere il risultato senza condizioni aggiuntive. Se è un numero intero, forse 0 sarà sufficiente, se è un hash, hash vuoto. eccetera.

La premessa è di non forzare il codice chiamante per gestire immediatamente i problemi. Il codice chiamante potrebbe non volersi preoccupare di loro. Questo è anche il motivo per cui in molti casi le eccezioni sono migliori di zero.


2
Questo è lo schema degli oggetti nulli menzionato in questa risposta: stackoverflow.com/questions/1274792/…
Scott Dorman,

L'idea qui è che in caso di errore, si restituisce una versione vuota / vuota di qualsiasi tipo di oggetto restituiresti normalmente. Una matrice o stringa vuota funzionerebbe per quei casi, per esempio. Restituire "NULL" è appropriato quando normalmente si restituisce un puntatore (poiché NULL è essenzialmente un puntatore vuoto). Restituire NULL in caso di errore da una funzione che normalmente restituisce, diciamo, un hash può essere fonte di confusione. Alcune lingue lo gestiscono meglio di altre, ma in generale la coerenza è la migliore pratica.
BTA

Non si ritorna necessariamente sull'errore, a meno che l'errore non stia in qualche modo controllando il flusso (che non è una buona pratica) o estratto nell'API o nell'interfaccia. Gli errori sono lì per propagarsi a qualsiasi livello su cui decidi di prenderlo, quindi non devi affrontarlo nel contesto di chiamata. Sono di default null-object-pattern-friendly.
Max Chernyak,

Sfortunatamente, il codice chiamante non considera sempre il caso di una raccolta vuota (proprio come non considera il caso nullo). Questo può o meno essere un problema.
Sridhar Sarnobat,

38

Buoni usi di restituzione null:

  • Se null è un risultato funzionale valido , ad esempio: FindFirstObjectThatNeedsProcessing () può restituire null se non trovato e il chiamante dovrebbe controllare di conseguenza.

Usi errati: cercare di sostituire o nascondere situazioni eccezionali come:

  • cattura (...) e ritorna null
  • Inizializzazione dipendenza API non riuscita
  • Spazio su disco insufficiente
  • Parametri di input non validi (errore di programmazione, gli input devono essere disinfettati dal chiamante)
  • eccetera

In quei casi, è più appropriato lanciare un'eccezione poiché:

  • Un valore di ritorno nullo non fornisce informazioni di errore significative
  • Molto probabilmente il chiamante immediato non è in grado di gestire la condizione di errore
  • Non vi è alcuna garanzia che il chiamante stia verificando risultati nulli

Tuttavia, le eccezioni non devono essere utilizzate per gestire le normali condizioni operative del programma come:

  • Nome utente / password non validi (o eventuali input forniti dall'utente)
  • Anelli di rottura o come gotos non locali

7
"Nome utente non valido" sembra tuttavia una buona causa per un'eccezione.
Thilo,

11
Gli utenti che inseriscono login / password non validi non devono essere trattati come condizioni eccezionali, che fanno parte del normale funzionamento del programma. Tuttavia, il sistema di autenticazione che non risponde (ad es. Active directory) è una condizione eccezionale.
ZeroConcept,


2
Direi che dipende: boolean login(String,String)sembra che AuthenticationContext createAuthContext(String,String) throws AuthenticationException
vada

1
Nel tuo esempio, se non esiste un primo oggetto che deve essere elaborato, esistono due modi ragionevoli per gestire quel caso. Il primo è il modello Null Object. Creare una sottoclasse finale che rappresenta una versione inesistente della classe. Ha impostazioni predefinite ragionevoli e genera eccezioni quando sono richieste azioni senza senso. L'altra tecnica è Opzione. Questo è ciò che è disponibile in Java8 e Scala. Ognuno di questi mostra l'intenzione degli sviluppatori. null non può mostrare l'intento perché ha troppi significati possibili. ** Mostra intento ** è l'aspetto più importante del codice.
Scott Gardner

29

Sì, restituire NULL è un design terribile , nel mondo orientato agli oggetti. In breve, l'utilizzo di NULL porta a:

  • gestione degli errori ad hoc (anziché eccezioni)
  • semantico ambiguo
  • lento invece di fallimento veloce
  • il pensiero del computer invece del pensiero dell'oggetto
  • oggetti mutabili e incompleti

Controlla questo post sul blog per una spiegazione dettagliata: http://www.yegor256.com/2014/05/13/why-null-is-bad.html . Maggiori informazioni nel mio libro Oggetti eleganti , sezione 4.1.


2
Sono pienamente d'accordo. Non mi piace nemmeno il modello a oggetti nulli che sembra essere una tattica di ritardo 'whitewash'. Si suppone che il tuo metodo abbia sempre successo o potrebbe non esserlo. Se dovesse sempre avere successo, lancia. Se il problema persiste, progettare il metodo in modo che il consumatore lo sappia, ad es. bool TryGetBlah(out blah)O FirstOrNull()oppure MatchOrFallback(T fallbackValue).
Luke Puplett,

Anche a me non piace restituire null. Stai separando la causa principale dal sintomo, rendendo più difficile il debug. O lanciare un'eccezione (fail fast) o chiamare un metodo checker che restituisce prima un valore booleano (ad esempio isEmpty()) e solo se è vero quindi chiamare il metodo. Le persone discutono contro il secondo affermando che sono prestazioni peggiori, ma come dice Unix Philosophy, "valorizzano il tempo umano rispetto al tempo macchina" (ovvero le prestazioni banalmente più lente sprecano meno tempo rispetto agli sviluppatori che eseguono il debug del codice che genera errori spuri).
Sridhar Sarnobat,

22

Chi dice che questo è cattivo design?

Il controllo di null è una pratica comune, anche incoraggiata, altrimenti si corre il rischio di NullReferenceExceptions ovunque. È meglio gestire l'errore con garbo piuttosto che generare eccezioni quando non è necessario.


11
+1. Il codice che genera eccezioni per problemi che possono essere mitigati sul posto mi rende triste.
jkeys,

6
Quanto ti rattristi quando i programmatori dimenticano di verificare la presenza di null e quindi di ottenere misteriose eccezioni al puntatore null? Eccezioni verificate, in cui il compilatore ricorda all'utente di non aver gestito le condizioni di errore per evitare la classe di errori di codifica.
djna,

3
@djna: Immagino sia anche triste, ma ho scoperto che lo stesso tipo di programmatori che "dimenticano" di verificare la presenza di null sono quelli che quando si occupano delle eccezioni controllate finiscono spesso per ingoiarli.
Randy supporta Monica il

5
È più facile individuare la presenza di un blocco catch vuoto rispetto all'assenza di un controllo null.
Preston,

20
@Preston: non sono assolutamente d'accordo. L'assenza di un controllo null individuerà immediatamente, quando si blocca. Le eccezioni inghiottite possono propagare errori misteriosi e sottili per anni ...
Beska,

18

Sulla base di ciò che hai detto finora, penso che non ci siano abbastanza informazioni.

Restituire null da un metodo CreateWidget () sembra male.

Restituire null da un metodo FindFooInBar () sembra a posto.


4
Simile alla mia convenzione: query a elemento singolo : Create...restituisce una nuova istanza o genera ; Get...restituisce un'istanza esistente prevista o genera ; GetOrCreate...restituisce un'istanza esistente o una nuova istanza se nessuna esiste o genera ; Find...restituisce un'istanza esistente, se esiste, onull . Per le query di raccolta: Get... restituisce sempre una raccolta, che è vuota se non viene trovato alcun elemento corrispondente.
Johann Gerell,

NULL è male per i motivi indicati nella risposta di yegor256 e hakuinin, la restituzione di un oggetto valido ma vuoto semplifica l'overal del ragionamento
Rob11311


10

Dipende dalla lingua che stai usando. Se sei in una lingua come C # in cui il modo idiomatico di indicare la mancanza di un valore è restituire null, allora restituire null è un buon progetto se non hai un valore. In alternativa, in linguaggi come Haskell che usano idiomaticamente la monade Maybe per questo caso, restituire null sarebbe un cattivo progetto (se fosse possibile).


2
+1 per menzionare forse monade. Trovo che la definizione di nullin linguaggi come C # e Java sia spesso sovraccarica e abbia un certo significato nel dominio. Se cerchi la nullparola chiave nelle specifiche della lingua, significa semplicemente "un puntatore non valido". Ciò probabilmente non significa nulla in alcun dominio problematico.
MattDavey,

Il problema è che non sai se si tratta di un "valore mancante" nullo "non inizializzato"null
CervEd

5

Se leggi tutte le risposte diventa chiaro che la risposta a questa domanda dipende dal tipo di metodo.

In primo luogo, quando accade qualcosa di eccezionale (IOproblema ecc.), Si generano eccezioni logiche. Quando esattamente qualcosa è eccezionale è probabilmente qualcosa per un argomento diverso ..

Ogni volta che ci si aspetta che un metodo non abbia risultati, ci sono due categorie:

  • Se è possibile restituire un valore neutro, farlo .
    Enumrable vuoti, stringhe ecc. Sono buoni esempi
  • Se non esiste un valore così neutro, è necessario restituire null .
    Come accennato, si presume che il metodo non abbia alcun risultato, quindi non è eccezionale, quindi non dovrebbe generare un'eccezione. Un valore neutro non è possibile (ad esempio: 0 non è particolarmente un risultato neutro, a seconda del programma)

Fino a quando non avremo un modo ufficiale per indicare che una funzione può o non può restituire null, provo ad avere una convenzione di denominazione per indicarlo.
Proprio come hai la convenzione Try Something () per i metodi che dovrebbero fallire, spesso nomina i miei metodi Safe Something () quando il metodo restituisce un risultato neutro anziché null.

Non sono ancora completamente d'accordo con il nome, ma non ho potuto trovare qualcosa di meglio. Quindi sto correndo con quello per ora.


4

Ho una convention in quest'area che mi ha servito bene

Per query a singolo elemento:

  • Create...restituisce una nuova istanza o genera
  • Get...restituisce un'istanza esistente prevista o genera
  • GetOrCreate...restituisce un'istanza esistente o una nuova istanza se nessuna esiste o genera
  • Find...restituisce un'istanza esistente, se esiste, onull

Per le query di raccolta:

  • Get... restituisce sempre una raccolta, che è vuota se non viene trovato alcun elemento [1] corrispondente

[1] dati alcuni criteri, espliciti o impliciti, indicati nel nome della funzione o come parametri.


Perché GetOne e FindOne ritornano diversi se non vengono trovati?
Vladimir Vukanac,

Ho descritto la differenza. Uso Getquando mi aspetto che sia lì, quindi se non c'è, allora è un errore e lancio - Non ho mai bisogno di controllare il valore di ritorno. Lo uso Findse davvero non so se è lì o no - quindi devo controllare il valore di ritorno.
Johann Gerell,

3

Le eccezioni sono per tutte le circostanze eccezionali .

Se la tua funzione è destinata a trovare un attributo associato a un determinato oggetto e tale oggetto non ha tale attributo, potrebbe essere appropriato restituire null. Se l'oggetto non esiste, lanciare un'eccezione può essere più appropriato. Se la funzione ha lo scopo di restituire un elenco di attributi, e non ce ne sono nessuno da restituire, ha senso restituire un elenco vuoto: stai restituendo tutti gli attributi zero.


1
Se si tenta di utilizzare un attributo senza valore, merita un'eccezione. (Suppongo che le tue specifiche affermino che l'attributo è facoltativo.) Avere un metodo separato per verificare se il suo valore è stato impostato.
Preston,

3

Va bene restituire null se farlo è significativo in qualche modo:

public String getEmployeeName(int id){ ..}

In un caso come questo è significativo restituire null se l'id non corrisponde a un'entità esistente, in quanto consente di distinguere il caso in cui non è stata trovata alcuna corrispondenza da un errore legittimo.

Le persone potrebbero pensare che ciò sia negativo perché può essere abusato di un valore di ritorno "speciale" che indica una condizione di errore, che non è così buona, un po 'come restituire i codici di errore da una funzione ma confuso perché l'utente deve controllare il ritorno per null, invece di cogliere le opportune eccezioni, ad es

public Integer getId(...){
   try{ ... ; return id; }
   catch(Exception e){ return null;}
}

3
Sì. Se hai una condizione di errore, genera un'eccezione.
David Thornley,

3
Questo è un caso in cui sarebbe giustificata un'eccezione. Se stai richiedendo il nome di un dipendente che non esiste, qualcosa ovviamente va storto.
Thorarin,

Penso che sia un po 'letterale, Thorarin, puoi cavillare con il mio esempio, certamente, ma sono sicuro che puoi immaginare qualche istanza di una funzione che restituisce un valore corrispondente, o null se non c'è corrispondenza. Che ne dici di ottenere un valore da una chiave in una tabella hash? (Avrei dovuto pensare a quell'esempio in primo luogo).
Steve B.

1
Una tabella hash che restituisce null per una chiave che non esiste è errata. In questo modo automaticamente significa che non è possibile memorizzare null come valore senza codice incoerente.
RHSeeger,

3

Non è necessariamente un cattivo design - come con così tante decisioni di design, dipende.

Se il risultato del metodo è qualcosa che non avrebbe un buon risultato nell'uso normale, la restituzione di null va bene:

object x = GetObjectFromCache();   // return null if it's not in the cache

Se davvero ci dovesse essere sempre un risultato non nullo, potrebbe essere meglio generare un'eccezione:

try {
   Controller c = GetController();    // the controller object is central to 
                                      //   the application. If we don't get one, 
                                      //   we're fubar

   // it's likely that it's OK to not have the try/catch since you won't 
   // be able to really handle the problem here
}
catch /* ... */ {
}

2
Sebbene sia possibile registrare un errore diagnostico proprio lì, forse è possibile ripetere l'eccezione. A volte First Capture Data Capture può essere molto utile.
djna,

Oppure racchiudere l'eccezione in RuntimeException con le informazioni di diagnostica nella stringa di messaggio. Tieni insieme le informazioni.
Thorbjørn Ravn Andersen,

Ora (nel 2018) non posso più essere d'accordo e in tali casi dovremmo favorire il ritornoOptional<>
Piotr Müller,

2

Per alcuni scenari, si desidera notare un errore non appena si verifica.

Controllare contro NULL e non affermare (per errori del programmatore) o lanciare (per errori dell'utente o del chiamante) nel caso di errore può significare che i crash successivi sono più difficili da rintracciare, perché il caso dispari originale non è stato trovato.

Inoltre, ignorare gli errori può portare a exploit di sicurezza. Forse la nullità deriva dal fatto che un buffer è stato sovrascritto o simili. Ora, si sta senza schiantarsi, il che significa che lo sfruttatore ha la possibilità di eseguire nel codice.


2

Quali alternative vedi per restituire null?

Vedo due casi:

  • findAnItem (id). Cosa dovrebbe fare se l'articolo non viene trovato

In questo caso potremmo: Restituire Null o lanciare un'eccezione (selezionata) (o magari creare un oggetto e restituirlo)

  • listItemsMatching (criteri) cosa dovrebbe restituire se non viene trovato nulla?

In questo caso potremmo restituire Null, restituire un elenco vuoto o generare un'eccezione.

Credo che il ritorno null possa essere meno buono delle alternative in quanto richiede al client di ricordare di verificare la presenza di null, i programmatori dimenticano e codificano

x = find();
x.getField();  // bang null pointer exception

In Java, il lancio di un'eccezione controllata, RecordNotFoundException, consente al compilatore di ricordare al client di gestire il caso.

Trovo che le ricerche che restituiscono elenchi vuoti possano essere abbastanza convenienti: basta popolare il display con tutto il contenuto dell'elenco, oh è vuoto, il codice "funziona".


3
Se si generano eccezioni per indicare una condizione che potrebbe verificarsi durante il normale flusso del programma, si ottiene un codice veramente brutto, del tipo try {x = find ()} catch (RecordNotFound e) {// do stuff}.
quant_dev,

Restituire liste vuote è una buona soluzione ma solo quando il metodo è in un contesto che può restituire liste. Per situazioni "findById", è necessario restituire null. Non mi piacciono le eccezioni RecordNotFound.
Thilo,

Quindi questo è il nocciolo della nostra differenza nell'opinione. Ai miei occhi non c'è molta differenza nella bellezza tra x = find (); if (x = null) {work} else {do ​​stuff} e prova a catturare. E, se necessario, sono pronto a sacrificare la bellezza per la correttezza del codice. Troppo spesso nella mia vita incontro codice in cui i valori di ritorno non sono stati controllati.
djna,

1

A volte, restituire NULL è la cosa giusta da fare, ma in particolare quando si ha a che fare con sequenze di diversi tipi (array, elenchi, stringhe, what-have-you) è probabilmente meglio restituire una sequenza di lunghezza zero, in quanto porta a un codice più breve e, si spera, più comprensibile, pur non impiegando molto di più a scrivere dall'implementatore API.



1

L'idea alla base di questo thread è programmare in modo difensivo. Cioè, codice contro l'imprevisto. Esiste una serie di risposte diverse:

Adamski suggerisce di guardare Null Object Pattern, con quella risposta votata per quel suggerimento.

Michael Valenty suggerisce anche una convenzione di denominazione per dire allo sviluppatore cosa ci si può aspettare. ZeroConcept suggerisce un uso corretto di Exception, se questo è il motivo del NULL. E altri.

Se stabiliamo la "regola" di voler sempre programmare in modo difensivo, allora possiamo vedere che questi suggerimenti sono validi.

Ma abbiamo 2 scenari di sviluppo.

Classi "create" da uno sviluppatore: l'autore

Classi "consumate" da un altro (forse) sviluppatore: lo sviluppatore

Indipendentemente dal fatto che una classe restituisca NULL per i metodi con un valore di ritorno o meno, lo sviluppatore dovrà verificare se l'oggetto è valido.

Se lo sviluppatore non può farlo, allora quel metodo / classe non è deterministico. Cioè, se la "chiamata del metodo" per ottenere l'oggetto non fa ciò che "pubblicizza" (ad esempio getEmployee) ha infranto il contratto.

Come autore di una classe, voglio sempre essere gentile e difensivo (e deterministico) quando creo un metodo.

Quindi, dato che NULL o NULL OBJECT (ad es. If (impiegato come NullEmployee.ISVALID)) devono essere controllati e che potrebbe essere necessario che si verifichi con una raccolta di dipendenti, l'approccio a oggetti nulli è l'approccio migliore.

Ma mi piace anche il suggerimento di Michael Valenty di nominare il metodo che DEVE restituire null, ad esempio getEmployeeOrNull.

Un autore che genera un'eccezione sta rimuovendo la scelta per lo sviluppatore di testare la validità dell'oggetto, il che è molto negativo per una raccolta di oggetti e costringe lo sviluppatore a gestire le eccezioni quando si ramifica il proprio codice di consumo.

Come sviluppatore che consuma la classe, spero che l'autore mi dia la possibilità di evitare o programmare la situazione nulla che la sua classe / i suoi metodi potrebbero dover affrontare.

Quindi come sviluppatore programmerei difensivamente contro NULL da un metodo. Se l'autore mi ha dato un contratto che restituisce sempre un oggetto (NULL OBJECT lo fa sempre) e quell'oggetto ha un metodo / proprietà con cui testare la validità dell'oggetto, allora userei quel metodo / proprietà per continuare a usare l'oggetto , altrimenti l'oggetto non è valido e non posso usarlo.

In conclusione, l'autore della classe / dei metodi deve fornire meccanismi che uno sviluppatore può utilizzare nella sua programmazione difensiva. Cioè, un'intenzione più chiara del metodo.

Lo sviluppatore dovrebbe sempre utilizzare la programmazione difensiva per testare la validità degli oggetti restituiti da un'altra classe / metodo.

Saluti

GregJF


0

Altre opzioni a questo sono: restituire un valore che indica il successo o meno (o il tipo di un errore), ma se hai solo bisogno di un valore booleano che indichi il successo / fallimento, restituendo null per errore e un oggetto per il successo non lo farebbe essere meno corretto, quindi restituire vero / falso e ottenere l'oggetto tramite il parametro.
Un altro approccio potrebbe usare l'eccezione per indicare i fallimenti, ma qui - ci sono in realtà molte più voci, che dicono che questa è una cattiva pratica (poiché usare le eccezioni può essere conveniente ma ha molti svantaggi).
Quindi personalmente non vedo nulla di male nel restituire null come indicazione che qualcosa è andato storto e controllarlo in seguito (per sapere effettivamente se ci sei riuscito o no). Inoltre, pensare ciecamente che il tuo metodo non restituirà NULL e quindi basare il tuo codice su di esso, può portare ad altri errori, a volte difficili da trovare (anche se nella maggior parte dei casi si bloccherà semplicemente il tuo sistema :), come ti riferirai a 0x00000000 prima o poi).


0

Durante lo sviluppo di programmi complessi possono insorgere funzioni nulle indesiderate e, come nel caso del codice morto, tali eventi indicano gravi difetti nelle strutture del programma.

Una funzione o un metodo null viene spesso utilizzato come comportamento predefinito di una funzione revectorable o metodo overrideable in un framework di oggetti.

Null_function @wikipedia


0

Bene, dipende sicuramente dallo scopo del metodo ... A volte, una scelta migliore sarebbe quella di lanciare un'eccezione. Tutto dipende da caso a caso.


0

Se il codice è simile a:

command = get_something_to_do()

if command:  # if not Null
    command.execute()

Se hai un oggetto fittizio il cui metodo execute () non fa nulla e lo restituisci al posto di Null nei casi appropriati, non devi controllare il caso Null e puoi invece semplicemente fare:

get_something_to_do().execute()

Quindi, qui il problema non è tra la ricerca di NULL rispetto a un'eccezione, ma è invece tra il chiamante che deve gestire i non casi speciali in modo diverso (in qualsiasi modo) o meno.


0

Per il mio caso d'uso avevo bisogno di restituire una mappa dal metodo e quindi cercare una chiave specifica. Ma se restituisco una mappa vuota, allora porterà a NullPointerException e quindi non sarà molto diverso restituendo null invece di una mappa vuota. Ma da Java8 in poi potremmo usare Opzionale . Quanto sopra è la vera ragione per cui è stato introdotto il concetto opzionale.


-3

Buongiorno,

Restituire NULL quando non si è in grado di creare un nuovo oggetto è pratica standard per molte API.

Perché diavolo è un cattivo design non ne ho idea.

Modifica: questo vale per le lingue in cui non si hanno eccezioni come C, dove è stata la convenzione per molti anni.

HTH

'Avahappy,


2
Se non riesci a creare un oggetto, dovresti davvero lanciare un'eccezione. Se non riesci a trovare un oggetto che corrisponda a una query, restituire null è la strada da percorrere.
Thilo,

@Thilo, mostrami come farlo in C e sarò molto interessato.
Rob Wells,

@RobWells C non è un linguaggio orientato agli oggetti, ma questa domanda è taggata come "oop"
yegor256

@ yegor256 Hai ragione. E ho perso il tag OOP originale. Ma, come ha detto BS, una classe in C ++ è solo una struttura con alcune funzioni aggiuntive per i membri e una gestione della memoria elaborata che avviene internamente. Ma se un'API viene utilizzata per restituire una struttura, la restituzione di NUL quando non è possibile creare la struttura è spesso la convenzione.
Rob Wells,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.