Question

Je pensais que Java avait une évaluation de court-circuit, mais cette ligne génère toujours une exception de pointeur nul:

if( (perfectAgent != null) && (perfectAgent.getAddress().equals(entry.getKey())) ) {

Dans ce cas, perfectAgent est null , je souhaite donc que l'expression entière renvoie false , mais mon application continue de planter. ligne avec une exception NullPointerException.

EDIT, réponse générale:

Puisque perfectAgent est null , rien à droite du & amp; & amp; ne doit être exécuté car il est impossible pour l'expression pour être vrai. Plus précisément, il est impossible d’exécuter perfectAgent.getAddress () car perfectAgent ne contient pas de référence valide (elle est null et all). J'essaie d'utiliser l'évaluation du court-circuit pour ne pas avoir à vérifier la valeur null dans une instruction distincte, car cela rend la logique plus bâclée.

EDIT 2 (ou, je suis un idiot): Ouais, comme dans beaucoup de choses de la vie, tu trouves la réponse juste après avoir annoncé au monde que tu es un crétin. Dans ce cas, j’avais désactivé la construction automatique d’Eclipse en faisant autre chose et ne l’avais pas réactivée. Je déboguais donc des fichiers de classe qui ne correspondaient pas à ma source.

Était-ce utile?

La solution

Leçon de débogage avancé n ° 1:

Si vous rencontrez une erreur apparemment impossible (par exemple, une erreur qui contredit vos connaissances sur Java), procédez comme suit:

  • Consultez un manuel réputé (ou mieux encore, le standard approprié) pour confirmer que votre compréhension n’est pas imparfaite. (Dans ce cas, votre compréhension était correcte et tout manuel peu convaincant le confirmerait dans un instant.)

  • Vérifiez toutes les choses stupides que vous auriez pu faire et qui pourraient causer l'erreur impossible. Des choses comme ne pas enregistrer un fichier, ne pas effectuer de construction complète, exécuter une ancienne version de l'application, se trouver dans le mauvais répertoire, etc.

En résumé, apprenez à douter un peu plus de vous-même.

Autres conseils

Si perfectAgent est véritablement null, ce code ne lève pas d'exception (au moins en supposant qu'il ne se passe pas d'étranges choses null à null à mi-parcours de l'expression). Je serais complètement choqué si vous pouviez produire un programme court mais complet le prouvant.

Alors, oui, votre intuition est juste - cela ne devrait pas être un problème. Cherchez ailleurs la cause. Je suspecte fortement que perfectAgent ne soit pas en réalité, et que vous rencontriez l'une des autres situations dans ce code qui pourrait provoquer une exception.

Je vous suggère d'essayer d'extraire ce morceau de code dans un exemple court mais complet. Si vous le pouvez, je mangerai mon chapeau métaphorique; Si ce n’est pas le cas, vous trouverez le problème lorsque vous tenterez l’extraction.

Qu'est-ce qui vous fait penser que perfectAgent est vraiment nul? Essayez d’insérer ce code avant:

if (perfectAgent == null)
{
    System.out.println("Yup, it's null");
}

Une autre possibilité très, très mince est que vous ayez rencontré un bogue JIT - mais j'en doute fortement.

Java a une évaluation du court-circuit. Peut-être que entrée est null et donc entry.getKey () est à l'origine de NullPointerException . Une autre possibilité est que getAddress () renvoie null ou ait une NullPointerException quelque part (si c'est plus compliqué qu'un simple retour déclaration).

EDIT: je vois votre modification à l'endroit où vous déclarez ceci:

  

Plus précisément, il est impossible d'exécuter perfectAgent.getAddress () ...

Mais que se passe-t-il si perfectAgent.getAddress () est exécuté avec succès et renvoie null ? Voyez ce que je veux dire ...

Vous vous assurez que perfectAgent n'est pas null, donc un ou plusieurs éléments parmi perfectAgent.getAddress () ou entrée ou . getKey () doit être null. Ou getAddress () ou getKey () atteignent un NPE dans leur implémentation.

Pour déboguer ce genre de chose, regardez d’abord le tracé de la pile pour déterminer l’emplacement. Cela vous indiquerait si cela se produit dans getAddress () ou dans getKey () ou dans l'extrait de code collé qui les appelle. Ensuite, si cela se trouve dans cet extrait, ajoutez du code avant le if pour tester, qui est null. Vous pouvez utiliser le bon vieux System.err.println () ou assertions . (Si vous utilisez des assertions, veillez à les activer avec l'indicateur -enableassertions de la commande java.)

Mise à jour: Mon interprétation s'est donc révélée fausse. Le problème présentait deux faits contradictoires (il y avait un NPE sur cette ligne et pourtant le court-circuit aurait dû se produire) et j'ai automatiquement Supposé que le premier fait était vrai et le second faux, alors qu’il s’agissait d’un problème entièrement différent du fait de la désactivation de la génération automatique dans Eclipse. Duh! En déboguant quelque chose "impossible" il est utile d’être radicalement sceptique.

Trois références autres que perfectAgent peuvent être nulles:

  • perfectAgent.getAddress ()
  • entrée
  • entry.getKey ()

Casser l'instruction ou l'exécuter dans un débogueur.

Grand mystère. J'ai copié votre ligne de code et testé avec perfectAgent == null , entrée == null , entry.getKey () == null et des combinaisons de ceux-ci: Pas de NPE dans mon banc d’essai (Java 1.6).

Quel que soit le problème, je doute que cela ait un rapport avec l’évaluation des courts-circuits. Si cette ligne est à l'origine du NPE, alors, autant que je sache, perfectAgent n'est pas nul. Bonne chance et montrez-nous le virus une fois que vous l'avez attrapé:)

Essayez de formater votre code comme suit:

if( 
  (perfectAgent != null) 
  && (
      perfectAgent.getAddress()
      .equals(
       entry.getKey()
      )
     ) 
  ) {

Cela devrait vous donner une meilleure entrée de ligne de trace de pile.

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