web-dev-qa-db-fra.com

Le constructeur peut-il retourner un objet nul?

En parcourant un ancien code, je suis tombé sur ce joyau:

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

La deuxième ligne est marquée dans Eclipse comme un code mort, et je comprends pourquoi. Aucune exception ne semble être explicitement levée, et il n'est pas possible pour le constructeur MyObject de lever tout type d'exception (tel que NullPointerExceptions).

Ma question est pourquoi il y a une vérification nulle? Était-il possible auparavant dans une ancienne version de Java pour un constructeur de retourner null? Ou est-ce simplement du code inutile et mort?

74
Jonathan Pitre

Le code est mort dans n'importe quelle version de Java. Il n'est pas possible pour un constructeur de renvoyer null, et même si une exception est levée par le constructeur, la ligne suivante ne sera pas appelée.

89
tibtof

Non, cela n'a jamais été possible. Peut-être qu'une version précédente du code utilisait une méthode d'usine qui pouvait retourner null:

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

De section 15.9.4 du JLS :

La valeur d'une expression de création d'instance de classe est une référence à l'objet nouvellement créé de la classe spécifiée. Chaque fois que l'expression est évaluée, un nouvel objet est créé.

Donc non, il ne peut jamais retourner null.

49
Jon Skeet

Je suppose qu'il a été écrit par un programmeur C qui est habitué à tester la valeur de retour de malloc() pour NULL, malloc() peut retourner NULL si votre système manque de mémoire.

Le code n'a pas de sens dans Java puisque Java lancera une OutOfMemoryError` s'il manque de mémoire).

23
Jack Edmonds

La réponse est simple: la personne qui a écrit le code était un programmeur c ++ paranoïaque. En C++, vous pouvez surcharger l'opérateur new et l'utiliser comme un simple allocateur de mémoire (aka malloc).

8
kofemann

C'était simplement du code mort inutile. Une fois que CTOR s'est exécuté avec succès, vous avez référence à l'objet.

4
Yair Zaslavsky

Lorsque vous créez un new Object (), vous créez une adresse en mémoire, et cette adresse n'est pas 'nulle', mais votre objet peut être vide.

Vous devez tester "null" pour l'objet transmis par les paramètres.

4
cl-r

C'est tout simplement du code mort.

new MyObject("parameter") ne renverra pas null dans aucune version de Java.

3
Alex Lockwood

Comme je l'ai découvert aujourd'hui, malgré ce qui est dit dans toutes les autres réponses, Foo x = new Foo(...) peut en effet retourner null, si ledit code s'exécute dans un test qui utilise PowerMock (ou un autre cadre de simulation) avec des effets similaires):

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

Dans ce cas, le code dans le (s) constructeur (s) de Foo est complètement contourné pour new Foo(...). Mais si vous écrivez un test où vous ne spécifiez pas la maquette de la manière ci-dessus, vous pouvez vous retrouver avec null à la place.

Mais même si vous utilisez un tel framework, vous ne voulez pas de code supplémentaire dans vos classes, juste pour gérer avec élégance le cas que vous avez oublié de bien se moquer des objets dans un test! Ce n'est pas un scénario réel où votre code est destiné à être exécuté. Code qui n'est actif que lorsque les tests doivent être éliminés de toute façon, et dans ce cas, il ne sera actif que pour un test cassé.

Donc, même si vous utilisez PowerMock, cette deuxième ligne doit à juste titre être considérée comme "code mort" et supprimée.

3
Zac Thompson