10
votes

Java: Est-ce correct de définir Integer = NULL?

J'ai une fonction qui renvoie un numéro d'identification si l'argument existe dans la base de données. Sinon, il retourne NULL. Est-ce que cela mendie une exception de pointeur nulle? Les numéros d'identification négative ne sont pas autorisés, mais je pensais qu'il serait plus clair d'avoir des arguments inexistants renvoyant null au lieu d'un code d'erreur comme -1. Que pensez-vous?

private Integer tidOfTerm(String name) throws SQLException {
    String sql = "SELECT tid FROM term_data WHERE name = ?";
    PreparedStatement prep = conn.prepareStatement(sql);
    prep.setString(1, name);
    ResultSet result = prep.getResultSet();

    if (result.next()) {
        return result.getInt("tid");
    }

    return null; // TODO: is this begging for a null pointer exception?
}


3 commentaires

Votre déclaration de retour pourrait être plus courte: Résultat de retour.Next ()? résultat.Getint ("TID")? nul;


@WILLI - Shorter! = Plus lisible


D'accord en général, mais cela lirait beaucoup mieux dans l'exemple ci-dessus.


14 Réponses :


0
votes

Non, ce ne sera pas. Il ne jettera qu'une NPE si vous utilisez ensuite, comme si c'était une primitive sans nullcher. Par exemple. i ++ et ainsi de suite. Votre exemple est valide (attendre à ce que le code JDBC lui-même fuit des ressources). Si vous n'avez pas besoin de l'identifiant réel , vous pouvez donc simplement renvoyer un booléen .


0 commentaires

2
votes

Je pense qu'il est légitime de retourner null dans ce cas. Assurez-vous simplement que l'intention est documentée correctement.

retourner une valeur négative dans ce cas irait bien, mais ce n'est pas une solution tout autour. Et si les valeurs négatives étaient autorisées dans la DB?

edit : Je veux ajouter un mot sur les discussions correspondantes sur les discussions relatives à la résolution des nulls ou des listes vides (ou des tableaux). Je suis en faveur du retour des listes ou des tableaux vides au lieu de NULL, mais le contexte est différent. Lorsque vous essayez d'obtenir une liste, il fait généralement partie d'un objet parent, et il est logique que l'objet parent ait une liste vide au lieu d'une référence null. Dans ce cas, NULL a une signification (= non trouvée) et il n'y a aucune raison d'éviter de le renvoyer.


0 commentaires

1
votes

J'espère que ce n'est pas une méthode réelle pour vous. Vous ne fermez pas la déclaration ou les résultatsset dans la portée de la méthode.


8 commentaires

Bons points, bien que ce n'est pas vraiment une réponse à la question.


Correct, mais il y a des moments où il ne reste que la question de la question n'est pas la meilleure politique. D'autres ont donné une réponse parfaitement acceptable qui répond à la lettre de la loi. Pourquoi le répéter simplement?


Je pense que le point de TM était de faire allusion que vous auriez dû poster un commentaire et non une réponse.


@harschaware - Oui, je sais ce que le point était. Je n'arrive pas à être d'accord avec ça. Ce que j'ai dit est tout à fait correct et approprié, et si je le mettais dans une réponse ou un commentaire ne me semble pas pertinent. Pourquoi devrait-il compter?


@duffymo - Parce que si vous mettez une réponse lorsqu'il n'a rien à voir avec la question de savoir, il est clair que votre simple traînée à la représentation. meta.stackexchange.com/questions/ 17447 / ...


Toujours juste un avis, pas de fait. Êtes-vous en train de dire que les personnes n'ont pas besoin de savoir que l'échec de la fermeture de ressources est une mauvaise chose? Je pense que c'est une bonne réponse. Et non, je ne suis pas la réputation de la rempartée ou de la traînée ou une autre chose négative que vous vous sentez habilitée à dire. La prochaine fois que Jon Skeet donne une réponse qui est un millimètre de sujet, je vous l'enverrai afin que vous puissiez lui appeler des noms.


@harschaware, peut-être que vous devriez avoir un vote au bas parce que vous ne connaissez pas la différence entre "c'est" et "sa". Avez-vous été nommé pour être un moniteur ou quelque chose? Comment ces commentaires sont-ils pertinents pour répondre à quoi que ce soit?


@duffymo: Les gens devraient être informés, c'était un excellent point qui serait bien pour un commentaire . Je ne t'ai pas dit que c'était une erreur mineure. Ok, "Trolling" était un peu négatif ... heureux tellement tellement.



-3
votes

Je suis d'accord avec les affiches. Entier est un wrapper et, en tant que tel, doit être utilisé pour des calculs, des conversions, etc. (que je pense que vous avez l'intention de faire). Ne retournez pas de null, utilisez un nombre négatif ... C'est un peu plus élégant et vous permet de contrôler davantage. IMHO.


1 commentaires

On risque de faire des calculs, des conversions, etc. avec le nombre négatif si on oublie de vérifier. Si on vérifie les nombres négatifs, on pourrait aussi bien vérifier NULL.



-3
votes

Oui, cela devrait causer une NPE et oui, vous devriez attraper cela dans la méthode d'appel (ou un autre endroit approprié). La raison la plus probable pour laquelle votre méthode reviendra NULL est quand il n'y a pas d'enregistrement et la bonne façon de gérer cela consiste à jeter une exception. Et l'exception parfaite pour dire à quelqu'un que vous n'avez pas ce qu'il a demandé est NPE.

retourner un code d'erreur (par exemple -1) n'est pas bon parce que:

a) S'il y a de nombreuses erreurs que vous souhaitez gérer (par exemple, vous ne pouvez pas lire dB, peut lire dB mais l'objet n'existe pas dans dB, objet trouvé, mais quelque chose est corrompu, etc.), puis renvoyer un code d'erreur ne fait pas de distinction entre les types d'erreurs.

b) à l'avenir si -1 devient un identifiant de termance légale, il sera difficile de le modifier (si vous devez utiliser -1, alors (modifier: en C) au moins faire #define ErrorCode -1 et utiliser Errorcode partout)


2 commentaires

Avez-vous simplement suggéré d'utiliser #define dans une question Java? (Je presque -1)


Ne vous dis pas de jeter une NPE. Mais vous devriez revenir volontiers nul et gérer cela dans la fonction d'appel. Si vous y accédez dans la fonction d'appel lorsque vous êtes NULL, vous devez attraper le NPE et travailler à partir de là. Pensez que je n'ai pas fait clairement sur le post original, mais vous obtenez ma dérive.



16
votes

Ceci est parfaitement légal. Si vous voulez éviter une NPE, lancez une exception personnalisée. Mais ne retourne pas un numéro négatif. Si l'appelant ne vérifie pas la valeur de retour, vous aurez toujours un problème. Mais faire faux le calcul (car le résultat est par exemple multiplié par -1) est définitivement plus difficile à déboguer qu'une exception non inconnue.


3 commentaires

Grand point, il y a en effet un danger que l'appelant effectue un faux calcul. C'est pourquoi je pense que la documentation est si importante. Comme je l'ai mentionné dans ma réponse, si je documente déjà le type de retour, je pourrais aussi bien le rendre null


En Java 8 (encore de quelques années à la question lorsque la question a été posée), vous devez utiliser en option à cet effet. Ajout de ce commentaire ici sur la réponse acceptée au cas où quelqu'un trébuche à travers cela.


En fait, facultatifint .



0
votes

Cela pourrait causer de gros problèmes pour les utilisateurs novices. Les bons codeurs reconnaîtront que si le nom est invalide, alors null pourrait être renvoyé. Cela dit que plus la chose standard est de lancer une exception .


0 commentaires

3
votes

retourner un null dans le cas d'une recherche qui ne donne pas de résultat est une méthode normale de représentation de la non-existence. Je choisirais cela dans ce cas. (Méthodes de recherche pour les classes de cartes Java standard sont un exemple d'utilisation de null au cas où la carte ne contient pas de clé.)

En ce qui concerne le retour d'une valeur spéciale pour l'ID, je ne proposerais que si votre système contient déjà des valeurs spéciales Repasent des identifiants spéciaux.

Une autre possibilité souvent entendue est de jeter une exception dans ce cas. Cependant, il n'est pas saint d'utiliser des exceptions pour réussir, donc je ne le ferais pas non plus.


2 commentaires

En ce qui concerne votre dernière phrase: pourquoi n'est-il pas sage d'utiliser des exceptions pour passer l'état et quel état serait adopté dans ce cas?


Dans ce cas, l'état passé serait la non-existence du nom dans la table. Des exceptions sont censées représenter des situations exceptionnelles qui ne se produisent pas normalement, tandis que l'état est transmis pendant une exécution normale - Utilisez des arguments de la méthode et des valeurs de retour pour l'état de passage. (Et la pile déroulant par des exceptions levées est moins performante qu'une valeur de retour.)



0
votes

Peut être délicat en combinaison de l'autoboxage. Si je fais cela:

final int tid = tidForTerm("term");


0 commentaires

-3
votes

S'il vous plaît ne pas écrire du code qui retourne null. Cela signifie que chaque appel à votre code doit vérifier pour NULL afin d'être robuste. À chaque fois. Toujours.

envisager de renvoyer une liste à la place contenant le nombre de valeurs de retour, qui pourraient être nulles.


7 commentaires

Comment "retourner une liste" pertinente lorsque le type de retour est entier?


Retourner null est parfaitement valide et très courant parmi d'innombrables API. Tant que vous le documentez, c'est absolument la bonne chose à faire.


@Skaffman. D'innombrables NPE ont eu lieu à partir de programmeurs ne vérifiant pas la valeur de retour contre NULL à partir de ces API. De plus, lorsque vous avez un `a (). B (). C () 'Construction dans une ligne, vous ne pouvez pas dire immédiatement lequel des appels ont donné la nullpointeException. Je pense que Jetbrains est absolument juste dans leur annotation @notnull. jetbrains.com/idea/documentation/howto.html


@duffymo, dans ce cas particulier, vous ne pouvez pas et un changement serait nécessaire. Avez-vous d'accord ou pas d'accord avec l'attitude envers les valeurs de retour nulelles?


On dirait dans ce cas particulier que la méthode renvoie un identifiant, une clé primaire. C'est ainsi que Hibernate marque une instance comme non sauvegardée: Onjava.com/pub/a/onjava/2006/09/13/... . L'hibernate est-il trompé mal? Je ne le pense pas.


Je conviens que la ligne directrice devrait ne pas renoncer à NULL dans la plupart des cas - mais "connaître les règles et savoir quand casser les règles" est toujours approprié.


Java efficace accepte que vous deviez renvoyer un objet vide plutôt que null afin de sauvegarder l'appelant A == Null Check



1
votes
  • N'utilisez pas de code d'erreur! Quelle valeur est l'erreur? ne deviendra jamais une valeur de retour juridique? Rien gagné.

  • null n'est pas bon. La plupart des indicateurs d'appelants doivent faire une vérification si non nulle pour le résultat. Et parfois, le Select peut renvoyer NULL. Devrait-il être traité différent de pas de rangée?

  • lancer une exception comme NoschelementException au lieu du retour null. C'est une exception décochée, l'appelant peut le gérer ou le transmettre. Et si l'appelant veut gérer, l'essai attrape n'est pas plus complexe qu'un null NULL.


0 commentaires

0
votes

Un problème intéressant et un grand nombre de solutions possibles:

  1. Créez une méthode Hasargument et nécessite que les utilisateurs l'appellent, problème, cela peut être lent et Duppliquez le travail
  2. lancer une exception si une valeur n'est pas dans la base de données, ne doit être utilisée que si cela est inattendu
  3. Utilisez des valeurs supplémentaires pour indiquer une valorisation de retour, null et négative non valide fonctionnerait pour vous, mais sinon vérifiée, ils pourraient causer des problèmes plus tard dans le code.
  4. renvoie une enveloppe avec une méthode isvalid () et getvalue (), où GetValue () jette une exception lorsqu'il n'est pas valide. Cela résoudrait les problèmes de 1 et 3, mais peut être un peu trop mutch.

0 commentaires

1
votes

Je vous suggère de considérer le modèle d'option.

Le modèle d'option agit comme une enveloppe autour de votre type retourné et définit deux cas spéciaux: option.none.none () et option.Some (). De cette façon, vous connaissez toujours votre type retourné (une option) et peut vérifier si vous avez une valeur dans votre objet d'option retourné à l'aide de méthodes telles que l'option.Some () et l'option.Isnone ().

De cette façon, vous pouvez vous garantir que vous n'avez pas de nulls non cochés.

Bien sûr, tout cela vient au coût de la complexité supplémentaire du code.

Pour plus d'informations sur le type d'option, voir ici ( Code Scala, mais même principal)


0 commentaires

0
votes

Je dirais que la meilleure solution dépend de ce que votre méthode est nommée et que vous devriez déterminer quelles sont vos méthodes nommées, s'ils devraient renvoyer nul ou jeter une exception.

titsofferm m'implique que le terme devrait exister, alors découvrez que l'on n'existe pas devrait lancer une exception.

Si le nom du terme est sous le contrôle de votre propre code et que vous ne trouvez pas qu'il indique un bogue dans votre code ou votre environnement, vous voudrez peut-être lancer une erreur illégale.

Si l'argument de nom du terme n'est pas sous votre contrôle, et que vous ne trouvez pas de termes valide, c'est une situation parfaitement valide, je renommerais votre méthode à quelque chose comme Findtidortermname donnant un léger indice que certains Un type de recherche sera effectué et qu'il est donc possible que la recherche ne trouve rien.


0 commentaires