Il costruttore può restituire un object nullo?

Mentre guardavo attraverso un vecchio codice mi sono imbattuto in questa gem:

MyObject o = new MyObject("parameter"); if (o == null) o = new MyObject("fallback parameter"); 

La seconda riga è contrassegnata in Eclipse come codice morto e capisco perché. Nessuna eccezione sembra essere esplicitamente generata, e non è ansible per il costruttore MyObject lanciare alcun tipo di eccezione (come NullPointerException s).

La mia domanda è perché c’è un assegno nulla? Era ansible in precedenza in una vecchia versione di Java che un costruttore restituisse null? O è semplicemente un codice inutile e morto?

Il codice è morto in qualsiasi versione di java. Non è ansible per un costruttore restituire null e anche se un’eccezione verrebbe generata dal costruttore, la riga successiva non verrà chiamata.

No, non è mai stato ansible. Forse una versione precedente del codice utilizzava un metodo factory che poteva restituire null:

 MyObject o = createMyObject("parameter"); if (o == null) o = createMyObject("fallback parameter"); 

Dalla sezione 15.9.4 della JLS :

Il valore di un’espressione di creazione di un’istanza di class è un riferimento all’object appena creato della class specificata. Ogni volta che viene valutata l’espressione, viene creato un nuovo object.

Quindi no, non può mai restituire null.

La mia ipotesi è che sia stato scritto da un programmatore C che viene utilizzato per testare il valore di ritorno di malloc() per NULL , malloc() può restituire NULL se il sistema esaurisce la memoria.

Il codice non ha senso in Java poiché Java genererà un OutOfMemoryError` se esaurisce la memoria.

La risposta è semplice: la persona che ha scritto il codice era un programmatore c ++ paranoico. In C ++ potresti sovraccaricare l’operatore e usarlo come un semplice allocatore di memoria (aka malloc).

Questo era semplicemente un codice morto inutilizzabile. Una volta che CTOR è stato eseguito correttamente, hai un riferimento all’object.

Quando crei un nuovo object () , crei un indirizzo in memoria e questo indirizzo non è “null”, ma il tuo object potrebbe essere vuoto.

Devi testare ‘null’ per Oggetto trasmesso da parametri.

È semplicemente un codice morto.

new MyObject("parameter") non restituirà null in nessuna versione di java.

Come ho scoperto oggi, nonostante ciò che è stato detto in tutte le altre risposte, Foo x = new Foo(...) può effettivamente restituire null, se detto codice è in esecuzione all’interno di un test che usa PowerMock (o qualche altro framework di simulazione con effetti simili) :

 PowerMockito.whenNew(Foo.class).withAnyArguments().thenReturn(mockFoo); 

In questo caso, il codice nel costruttore / i di Foo viene bypassato del tutto per il new Foo(...) . Ma se scrivi un test in cui non riesci a specificare il mock nel modo sopra riportato, potresti finire con null .

Ma anche se stai usando un framework di questo tipo, non vuoi un codice extra nelle tue classi, solo per gestire con grazia il caso che hai dimenticato di simulare correttamente gli oggetti in un test! Non è uno scenario reale in cui il tuo codice è destinato a essere eseguito. Codice che è sempre attivo solo quando i test dovrebbero essere eliminati comunque, e in questo caso sarebbe sempre attivo solo per un test non funzionante.

Quindi, anche se stai usando PowerMock, quella seconda linea dovrebbe essere giustamente considerata “codice morto” e rimossa.

Se la seconda riga è morta e la prima riga è l’unico modo in cui viene creato un object, suppongo che l’eccezione NullPointerException non possa mai verificarsi !!! (A meno che non abbiate eseguito qualcosa come 0.aMethod() . Ma ho sentito che in java anche gli interi sono oggetti, quindi forse in una lingua in cui non potete avere dei puntatori – non potete avere puntatori nulli.) (Un grande affare di sarcasmo in quanto sopra!)

Mi è già successo quando ho ignorato il metodo toString

 public String toString(){ return description; } 

non so perché ancora.