Question

Je viens d'un environnement .NET et je travaille maintenant en Java.

Actuellement, j'ai de gros problèmes pour concevoir une API de manière défensive contre les entrées défectueuses. Disons que j'ai le code suivant (assez proche):

public void setTokens(Node node, int newTokens) {
    tokens.put(node, newTokens);
}

Toutefois, ce code peut échouer pour deux raisons:

  1. L'utilisateur passe un noeud null .
  2. L'utilisateur passe un noeud non valide, c'est-à-dire un noeud non contenu dans le graphique.

Dans .NET, je lancerais un ArgumentNullException (plutôt qu'une NullReferenceException !) Ou un ArgumentException respectivement, en transmettant le nom de l'argument incriminé ( noeud ) en tant que string argument.

Java ne semble pas avoir d’exceptions équivalentes. Je me rends compte que je pourrais être plus spécifique et lancer n'importe quelle exception qui décrit le mieux la situation, ou même écrire ma propre classe d'exceptions pour la situation spécifique.

Est-ce la meilleure pratique? Ou existe-t-il des classes polyvalentes similaires à ArgumentException dans .NET?

Est-il même judicieux de vérifier par rapport à null dans ce cas? Le code échouera de toute façon et la trace de pile de l’exception contiendra l’appel de méthode ci-dessus. Vérifier par rapport à null semble redondant et excessif. Accordé, la trace de pile sera légèrement plus propre (puisque sa cible est la méthode ci-dessus, plutôt qu'une vérification interne dans l'implémentation HashMap de JRE). Mais cela doit être compensé par le coût d’une instruction supplémentaire si , qui, en outre, ne devrait jamais se produire de toute façon - après tout, en passant null à la méthode ci-dessus n'est pas une situation attendue, c'est un bogue plutôt stupide. S'attendre à ce qu'il soit complètement paranoïaque - & nbsp; et il échouera avec la même exception, même si je ne le vérifie pas.

[Comme il a été souligné dans les commentaires, HashMap.put autorise en réalité les valeurs null pour la clé. Donc, une vérification sur null ne serait pas nécessairement redondante ici.]

Était-ce utile?

La solution

Différents groupes ont des normes différentes.

Tout d'abord, je suppose que vous connaissez la différence entre RuntimeException s (décoché) et les Exception s normaux (coché), sinon, consultez la question et les réponses . Si vous écrivez votre propre exception, vous pouvez la forcer à être interceptée, alors que NullPointerException et IllegalArgumentException sont des exceptions RuntimeExceptions mal vues dans certains cercles.

Deuxièmement, comme avec vous, les groupes avec lesquels j'ai travaillé mais n'utilisent pas activement les assertions, mais si votre équipe (ou le consommateur de l'API) a décidé d'utiliser des assertions, cette affirmation sonne exactement comme le mécanisme correct.

Si j'étais vous, j'utiliserais NullPointerException . La raison en est un précédent. Prenons un exemple d'API Java de Sun, par exemple java.util.TreeSet . Cela utilise des NPE pour précisément ce genre de situation, et bien que votre code ressemble à un code null, il est tout à fait approprié.

Comme d'autres l'ont déjà dit, IllegalArgumentException est une option, mais je pense que NullPointerException est plus communicatif.

Si cette API est conçue pour être utilisée par des sociétés / équipes extérieures, je resterais avec NullPointerException , mais assurez-vous qu'elle est déclarée dans le javadoc. Si c'est pour un usage interne, vous pouvez décider que l'ajout de votre propre hiérarchie Exception en vaut la peine, mais personnellement, je trouve les API qui ajoutent d'énormes hiérarchies d'exceptions, qui ne seront que printStackTrace () d ou journalisées. ne sont qu'une perte d’effort.

En fin de compte, l’essentiel est que votre code communique clairement. Une exception locale correspond à du jargon local: elle ajoute des informations aux initiés, mais peut dérouter les étrangers.

En ce qui concerne la vérification de null, je dirais que cela a du sens. Tout d'abord, cela vous permet d'ajouter un message sur ce qui était nul (nœud ou jetons) lorsque vous construisez l'exception, ce qui serait utile. Deuxièmement, à l'avenir, vous pourriez utiliser une implémentation Map qui autorise null , et vous perdriez alors le contrôle d'erreur. Le coût est presque nul, donc à moins qu'un profileur dise qu'il s'agit d'un problème de boucle interne, je ne m'en inquiéterais pas.

Autres conseils

L'exception Java standard est IllegalArgumentException . Certains lanceront NullPointerException si l'argument est null, mais pour moi, NPE indique que "quelqu'un a foiré" et que connotation, et vous ne voulez pas que les clients de votre API pensent que vous ne savez pas ce que vous faites.

Pour les API publiques, vérifiez les arguments et échouez rapidement et proprement. Le temps / coût importe à peine.

En Java, vous lancerez normalement une exception IllegalArgumentException

Si vous souhaitez un guide sur la rédaction de code Java performant, je vous recommande vivement le livre Effective Java de Joshua Bloch.

Cela semble être une utilisation appropriée pour un affirmer :

public void setTokens(Node node, int newTokens) {
    assert node != null;
    tokens.put(node, newTokens);
}

Votre approche dépend entièrement du contrat que votre fonction offre aux appelants. Le nœud n'est-il pas une condition préalable?

Si c'est le cas, vous devriez lever une exception si node est null, car il s'agit d'une violation de contrat. Si ce n'est pas le cas, votre fonction doit gérer le nœud nul et répondre en conséquence de manière silencieuse.

Je pense que cela dépend beaucoup du contrat de la méthode et de la qualité de la connaissance de l'appelant.

À un moment donné du processus, l'appelant peut prendre des mesures pour valider le noeud avant d'appeler votre méthode. Si vous connaissez l'appelant et savez que ces nœuds sont toujours validés, je pense qu'il est correct de supposer que vous obtiendrez de bonnes données. La responsabilité incombe essentiellement à l'appelant.

Cependant, si vous fournissez, par exemple, une bibliothèque tierce distribuée, vous devez valider le nœud pour les valeurs NULL, etc ...

Une illégaleArugementException est la norme Java mais est également une exception RunTimeException. Donc, si vous voulez forcer l'appelant à gérer l'exception, vous devez fournir une exception de contrôle, probablement une exception personnalisée que vous créez.

Personnellement, je voudrais que NullPointerExceptions se produise UNIQUEMENT par accident. Vous devez donc utiliser un autre élément pour indiquer qu’une valeur d’argument non conforme a été transmise. IllegalArgumentException convient pour cela.

if (arg1 == null) {
 throw new IllegalArgumentException("arg1 == null");
}

Cela devrait être suffisant à la fois pour ceux qui lisent le code, mais également pour la pauvre âme qui reçoit un appel de support à 3 heures du matin.

(et, TOUJOURS fournir un texte explicatif pour vos exceptions, vous les apprécierez un jour triste)

comme l’autre: java.lang.IllegalArgumentException. À propos de la vérification du nœud nul, qu’en est-il de la vérification d’une mauvaise entrée lors de la création du nœud?

Je n'ai à faire plaisir à personne, donc ce que je fais maintenant en tant que code canonique est

void method(String s) 

if((s != null) && (s instanceof String) && (s.length() > 0x0000))
{

ce qui me procure beaucoup de sommeil.

D'autres ne seront pas d'accord.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top