Qu'est ce qu'un NullPointerException, et comment puis-je résoudre ce problème?
Ce sont de Pointeur Null Exceptions (java.lang.NullPointerException
) et ce qui les provoque?
Quelles sont les méthodes/outils peuvent être utilisés pour déterminer la cause de sorte que vous arrêtez l'exception de causer le programme de résilier prématurément?
OriginalL'auteur |
Vous devez vous connecter pour publier un commentaire.
Lorsque vous déclarez une variable de référence (c'est à dire un objet) vous êtes vraiment à la création d'un pointeur vers un objet. Considérons le code suivant où vous déclarez une variable de type primitif
int
:Dans cet exemple, la variable x est une
int
et Java va initialiser à 0 pour vous. Lorsque vous affectez à 10 dans la deuxième ligne de votre valeur 10 est écrit dans l'emplacement mémoire pointé par x.Mais, lorsque vous essayez de déclarer le type d'une référence à quelque chose de différent se passe. Prenez le code suivant:
La première ligne déclare une variable nommée
num
, mais, il ne contient pas une valeur primitive. Au lieu de cela, il contient un pointeur (parce que le type estInteger
qui est un type de référence). Puisque vous n'avez pas le dire encore ce que du point de Java il met à null, ce qui signifie "je suis pointant sur rien".Dans la deuxième ligne, le
new
mot-clé est utilisé pour instancier (ou créer) un objet de type Integer et le pointeur de variablenum
est affecté à cet objet. Vous pouvez désormais référence à l'objet à l'aide de l'opérateur de déréférencement.
(un point).La
Exception
que vous m'avez demandé se produit lorsque vous déclarez une variable, mais n'a pas créer un objet. Si vous tentez de le déréférencernum
AVANT la création de l'objet, vous obtenez unNullPointerException
. Dans la plupart des cas triviaux, le compilateur va attraper le problème et de vous laisser savoir que "num n'aient pas été initialisé", mais parfois vous écrivez du code qui ne crée pas directement de l'objet.Par exemple, vous pouvez avoir une méthode comme suit:
Dans ce cas, vous ne sont pas la création de l'objet
obj
, plutôt en supposant qu'il a été créé avant ladoSomething
méthode a été appelée. Malheureusement, il est possible d'appeler la méthode comme ceci:Auquel cas
obj
est null. Si la méthode est destinée à faire quelque chose pour le passé-dans l'objet, il convient de jeter leNullPointerException
parce que c'est une erreur du développeur et programmeur aurez besoin de cette information à des fins de débogage.Alternativement, il peut y avoir des cas où le but de la méthode n'est pas le seul à fonctionner sur le passé dans l'objet, et par conséquent un paramètre null peut être acceptable. Dans ce cas, vous avez besoin de vérifier pour un paramètre null et se comporter différemment. Vous devez également expliquer dans la documentation. Par exemple,
doSomething
peut être écrite comme:Enfin, Comment repérer l'exception & cause à l'aide de la Trace de Pile
Je voudrais ajouter une remarque à propos de ce poste en expliquant que même les affectations de primitives peuvent causer des Npe lors de l'utilisation de l'autoboxing:
int a=b
pouvez jeter un NPE si b est unInteger
. Il y a des cas où cela est source de confusion pour le débogage.Est-il possible de capturer des entrées en phase nationale lancée par une webapp à partir du navigateur web?comme va l'afficher dans la vue source de la page à partir du navigateur web..
Oui vérifier si l'objet est égale à null avant d'appeler une méthode ou d'essayer d'accéder à une variable qu'il pourrait avoir. Certaines fois de structurer votre code peut aider à éviter exception de pointeur null. par exemple lors de la vérification d'une chaîne d'entrée avec une constante chaîne de caractères, vous devriez commencer avec la constante de chaîne comme ici: si ("SomeString".equals(inputString)) {} //même si inputString est null aucune exception n'est levée. Il y a donc un tas de choses que vous pouvez faire pour essayer d'être en sécurité.
Un autre moyen d'éviter
NullPointerException
problèmes dans votre code est à utiliser@Nullable
et@NotNull
annotations. Le suivant répondre a plus d'informations sur cette. Bien que cette réponse est specificially sur les Ide, IDE, il est également applicable à d'autres outils comme apparanet de teh commentaires. (BTW, je ne suis pas autorisé à modifier cette réponse directement, peut-être l'auteur peut ajouter?)OriginalL'auteur
NullPointerException
s sont les exceptions qui se produisent lorsque vous essayez d'utiliser une référence qui pointe vers aucun endroit dans la mémoire (null) comme s'il s'agissait d'une référence à un objet. Appel d'une méthode sur une référence null ou essayer d'accéder à un champ d'une référence null sera le déclencheur d'uneNullPointerException
. Ce sont les plus communs, mais d'autres moyens sont répertoriés sur leNullPointerException
javadoc page.Probablement le moyen le plus rapide code d'exemple qui me vient en tête pour illustrer un
NullPointerException
serait:Sur la première ligne à l'intérieur de
main
, je suis à la définition explicite de laObject
référenceobj
égal ànull
. Cela signifie que j'ai une référence, mais il n'est pas pointant vers n'importe quel objet. Après, j'ai essayer de traiter la référence, comme si elle pointe vers un objet par l'appel d'une méthode sur elle. Il en résulte uneNullPointerException
car il n'y a pas de code à exécuter dans l'emplacement de la référence est de pointage.(C'est un vice de forme, mais je pense qu'il est à souligner: Une référence qui pointe vers null n'est pas le même comme un C pointeur qui pointe vers un emplacement de mémoire non valide. Un pointeur null est littéralement pas de pointage n'importe où, qui est subtilement différent que de pointer vers un emplacement qui se trouve être non valide.)
Merci pour les commentaires, vous faites un point valide. Il est difficile sur internet pour vraiment juger au cas où quelqu'un est à, et à ce niveau, il est sûr de commencer une explication. Je vais essayer de réviser le présent de nouveau.
D'une façon plus commune pour obtenir une NullPointerException dans la pratique serait oublier explicitement initialiser une variable de membre à quelque chose d'autre que
null
avant de l'utiliser, comme ceci. Avec des variables locales, le compilateur aurait rattraper cette erreur, mais dans ce cas, il ne le fait pas. Peut-être que ça ferait un complément utile à votre réponse?pointeur null est littéralement ne pointe pas n'importe où..."
Ce qui est exactement ce que ce point est souligné.
OriginalL'auteur
Ce qui est une exception NullPointerException?
Un bon endroit pour commencer est le La documentation javadoc. Ils ont cette couvertes:
C'est également le cas si vous essayez d'utiliser une référence null avec
synchronized
, qui sera également de se débarrasser de cette exception, par JL:Comment puis-je résoudre ce problème?
Si vous avez un
NullPointerException
. Comment voulez-vous résoudre ce problème? Prenons un exemple simple qui jette unNullPointerException
:Identifier les valeurs null
La première étape est d'identifier exactement les valeurs qui sont à l'origine de l'exception. Pour cela, nous avons besoin de faire un peu de débogage. Il est important d'apprendre à lire un stacktrace. Cela va vous montrer où l'exception a été levée:
Ici, nous voyons que l'exception est levée sur la ligne 13 (dans le
printString
méthode). Regardez la ligne et de vérifier les valeurs null parl'ajout de des instructions de journalisation ou à l'aide d'un débogueur. Nous constatons que
s
est nulle, et l'appel de lalength
méthode lève une exception. Nous pouvons voir que le programme s'arrête de jeter l'exception lorsques.length()
est retiré de la méthode.Trace où ces valeurs viennent de
Prochaine case où cette valeur provient de. En suivant les appelants de la méthode, nous voyons que
s
est transmis avecprintString(name)
dans leprint()
méthode, etthis.name
est null.Trace où ces valeurs devraient être définies
Où est
this.name
ensemble? Dans lesetName(String)
méthode. Avec un peu plus de débogage, nous pouvons voir que cette méthode n'est pas appelée à tous. Si la méthode a été appelée, assurez-vous de vérifier la ordre que ces méthodes sont appelées, et l'ensemble de la méthode n'est pas appelée après la méthode d'impression.C'est assez pour nous donner une solution: ajouter un appel à
printer.setName()
avant d'appelerprinter.print()
.Autres correctifs
La variable peut avoir un valeur par défaut (et
setName
peut l'empêcher d'être mis à null):Le
print
ouprintString
méthode peut vérifier la valeur null, par exemple:Ou vous pouvez concevoir la classe de sorte que
name
a toujours une valeur non nulle:Voir aussi:
Je n'arrive toujours pas à trouver le problème
Si vous avez essayé de déboguer le problème et n'ont toujours pas de solution, vous pouvez poster une question pour plus d'aide, mais assurez-vous d'inclure ce que vous avez essayé jusqu'à présent. Au minimum, inclure la stacktrace dans la question, et marque l'important numéros de ligne dans le code. Aussi, essayez de simplifier le code en premier (voir SSCCE).
Vous avez mentionné le débogage...Comment ça marche? J'ai fait des recherches sur le sujet pendant un certain temps maintenant, mais ne peut rien trouver. Je suis sûr qu'un enseignant extraordinaire, comme vous pouvez l'enseigner à moi en une seconde! Merci beaucoup! 🙂
Un débogueur permet d'étape, à travers un programme ligne par ligne pour voir les méthodes qui sont appelées et la manière dont les variables sont modifiées. IDEs devrait avoir quelques outils pour ce faire. Voir vogella.com/tutorials/EclipseDebugging/article.html par exemple.
Définir des points d'arrêt sur les méthodes autour de tout NullPointerExceptions comme on le voit dans la stacktrace, et de vérifier les valeurs des variables à l'encontre de ce que vous attendez d'eux. Si vous connaissez une variable est null si elle ne devrait pas l'être, alors vous pouvez définir des points d'arrêt sur n'importe quel code qui modifie la valeur. Il y a aussi des points d'arrêt conditionnels vous pouvez utiliser qui vous dira quand une modification de valeur.
Réglage de la Chaîne des objets à une chaîne vide comme leur valeur par défaut est considéré comme une mauvaise pratique.
OriginalL'auteur
Question: Quelles sont les causes d'un
NullPointerException
(NPE)?Comme vous le savez déjà, les types Java sont divisés en types primitifs (
boolean
,int
, etc.) et types de référence. Les types de référence en Java vous permet d'utiliser la valeur spécialenull
qui est la Java façon de dire "sans objet".Un
NullPointerException
est levée lors de l'exécution à chaque fois que votre programme tente d'utiliser unnull
comme si c'était une vraie référence. Par exemple, si vous écrivez ceci:la déclaration de la mention "ICI" est en cours pour tenter d'exécuter les
length()
méthode sur unnull
de référence, et ce sera de jeter unNullPointerException
.Il existe de nombreuses façons que vous pouvez utiliser une
null
valeur qui donnera lieu à unNullPointerException
. En fait, les seules choses que vous peut faire avec unnull
sans causer de NPE sont:==
ou!=
opérateurs, ouinstanceof
.Question: Comment puis-je lire les NPE stacktrace?
Suppose que je le compiler et exécuter le programme ci-dessus:
Première observation: la compilation réussit! Le problème dans le programme n'est PAS une erreur de compilation. C'est un runtime erreur. (Quelques IDEs pouvez avertir votre programme sera toujours lancer une exception ... mais la norme
javac
compilateur ne le fait pas.)Deuxième observation: quand je lance le programme, il affiche deux lignes de "charabia". MAL!! Ce n'est pas charabia. C'est une stacktrace ... et il fournit des informations vitales qui vont vous aider à localiser l'erreur dans votre code, si vous prenez le temps de le lire attentivement.
Regardons donc ce qu'il dit:
La première ligne de la trace de la pile vous dit un certain nombre de choses:
java.lang.NullPointerException
.NullPointerException
est inhabituel à cet égard, car il a rarement un message d'erreur.La deuxième ligne est le plus important dans le diagnostic de l'une des NPE.
Cela nous indique un certain nombre de choses:
main
méthode de laTest
classe.Si vous comptez les lignes dans le fichier ci-dessus, la ligne 4 est celui que j'ai marqué avec le "ICI" en commentaire.
Note que, dans un exemple plus compliqué, il y aura beaucoup de lignes dans le NPE trace de la pile. Mais vous pouvez être sûr que la deuxième ligne (la première "en ligne") vous dira où le NPE a été jeté1.
En bref la trace de la pile nous dira sans ambiguïté de l'énoncé du programme a jeté les NPE.
1 - Pas tout à fait vrai. Il y a des choses que l'on appelle exceptions imbriquées...
Question: Comment puis-je déterminer la cause de la NPE exception dans mon code?
C'est la partie la plus difficile. La réponse courte est d'appliquer l'inférence logique de la preuve fournie par la trace de la pile, le code source et de la documentation de l'API.
Nous allons illustrer avec l'exemple simple (ci-dessus). Nous commençons par examiner la ligne que la trace de la pile nous a dit est l'endroit où les entrées en phase nationale qui s'est passé:
Comment pouvez jeter un NPE?
En fait il n'y a qu'une seule façon: il ne peut se faire que si
foo
a la valeurnull
. Nous avons ensuite essayez d'exécuter lelength()
méthode surnull
et .... BANG!Mais (je vous entends dire) que si le NPE a été jeté à l'intérieur de la
length()
appel de méthode?Bien, si cela arrivait, la trace de pile serait une apparence différente. Le premier "à la ligne" serait de dire que l'exception a été levée dans une certaine ligne dans le
java.lang.String
classe, et la ligne 4 deTest.java
serait le deuxième "à la ligne".Alors d'où vient que
null
venir? Dans ce cas, il est évident, et il est évident que nous devons faire pour le réparer. (Assigner une valeur non nulle àfoo
.)OK, essayons donc un peu plus délicat exemple. Cela exigera des déduction logique.
Alors maintenant, nous avons deux "à" des lignes. Le premier est pour cette ligne:
et le second est pour cette ligne:
À la recherche à la première ligne, comment pourrait jeter un NPE? Il y a deux façons:
bar
estnull
puisbar[pos]
va jeter un NPE.bar[pos]
estnull
, puis de l'appellength()
sur qu'il va jeter un NPE.Ensuite, nous avons besoin de comprendre lequel de ces scénarios explique ce qui se passe réellement. Nous allons commencer par explorer la première:
Où
bar
venir? C'est un paramètre à latest
appel de méthode, et si l'on regarde commenttest
a été appelé, nous pouvons voir qu'il s'agit de lafoo
variable statique. En outre, nous pouvons voir clairement que nous avons initialiséfoo
à une valeur non nulle. C'est suffisant pour essayer de rejeter cette explication. (En théorie, quelque chose d'autre pourrait changementfoo
ànull
... mais ce n'est pas ce qui se passe ici.)Alors que dire de notre deuxième scénario? Eh bien, nous pouvons voir que
pos
est1
, ce qui signifie qu'ilfoo[1]
doit êtrenull
. Est-ce possible?En effet il est! Et c'est le problème. Lorsque nous initialiser comme ceci:
nous allouons un
String[]
avec deux éléments qui sont initialisées ànull
. Après cela, nous n'avons pas changé le contenu defoo
... doncfoo[1]
sera toujoursnull
.OriginalL'auteur
C'est comme si vous essayez d'accéder à un objet qui est
null
. Considérons l'exemple ci-dessous:À ce moment, vous avez juste déclaré cet objet, mais pas initialisé ou instancié. Et à chaque fois que vous essayez d'accéder à une propriété ou une méthode en elle, qu'il va jeter
NullPointerException
qui a du sens.Voir cet exemple ci-dessous:
OriginalL'auteur
Une exception de pointeur null est renvoyée lorsqu'une application tente d'utiliser la valeur null dans le cas où un objet est requis. Elles comprennent:
null
objet.null
objet.null
comme si c'était un tableau.null
comme si c'était un tableau.null
comme si c'était un Throwable valeur.Applications devraient jeter les instances de cette classe pour indiquer que d'autres illégale de la
null
objet.Référence: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
simplement en accédant à un initialisé attribut ne provoque pas de NPE. C'est ce que vous >>ne<< non initialisée avec la valeur de l'attribut qui provoque les entrées en phase nationale.
C'est à partir de docs.oracle.com/javase/8/docs/api/java/lang/.... -1 pour la citation sans référence.
Si vous voulez plus de cas: 1) à l'aide d'un
null
comme la cible d'unesynchronized
bloc, 2) à l'aide d'unnull
comme la cible d'uneswitch
, et unboxingnull
.OriginalL'auteur
Un
NULL
pointeur qui pointe vers nulle part. Lorsque vous déréférencer un pointeurp
, vous dire "donnez-moi les données à l'emplacement stocké en "p". Lorsquep
est un pointeur null, la localisation stockées dansp
estnowhere
, vous êtes en train de dire "donnez-moi les données à l'emplacement 'nulle part'". De toute évidence, il ne peut pas le faire, donc il jette à unNULL pointer exception
.En général, c'est parce que quelque chose n'a pas été initialisé correctement.
NULL
est écrit commenull
en java. Et c'est un casse chose.Lol. @bvdb Froid.
"UN pointeur NULL est un qui pointe vers nulle part" je suis en désaccord. Pointeurs Null ne pointez pas de nulle part, ils soulignent les valeurs null.
Un pointeur null et un pointeur vers une valeur nulle sont des choses différentes - un pointeur null n'est pas une valeur null. Supposons que vous avez un pointeur vers un pointeur: pointeur Un des points de pointeur B, et le pointeur de B est nulle. Dans ce cas, Un pointeur pointe vers une valeur nulle, et le pointeur B est un pointeur null.
OriginalL'auteur
A beaucoup d'explications sont déjà présents pour expliquer comment il se produit et comment résoudre le problème, mais vous devez également suivre meilleures pratiques pour éviter
NullPointerException
à tous.Voir aussi:
Une bonne liste de meilleures pratiques
Je voudrais ajouter, très important, de faire un bon usage de la
final
modificateur.À l'aide de la "finale" modificateur, le cas échéant en Java
Résumé:
final
modificateur à appliquer une bonne initialisation.@NotNull
et@Nullable
if("knownObject".equals(unknownObject)
valueOf()
sur toString().StringUtils
méthodesStringUtils.isEmpty(null)
.Il est utile de mentionner que certaines IDEs (par exemple, Eclipse) offre de nullité de plein droit analyses basées sur personnalisable annotations (par exemple
@Nullable
comme indiqué ci-dessus) et de les avertir d'éventuelles erreurs. Il est également possible de déduire et de générer de telles annotations (par exemple, l'Ide peut le faire) fondés sur la structure du code.Première chose à faire est de avant à l'aide d'un objet nullable, vous devriez vérifier si il est nul, à l'aide de
if (obj==null)
.Si elle est nulle, alors vous devez écrire du code pour gérer aussi.OMI, il est préférable d'éviter le retour des objets null dans les méthodes, si possible, et utiliser les annotations lorsque la valeur null paramètres d'entrée ne sont pas admis dans l'ordre, par contrat, de réduire le montant de l'if (obj==null) dans le code, et d'améliorer la lisibilité du code.
Lire ceci ... avant d'accepter ces "meilleures pratiques" en vérité: satisfice.com/blog/archives/27
OriginalL'auteur
Une exception de pointeur null est un indicateur que vous utilisez un objet sans l'initialiser.
Par exemple, ci-dessous est un élève de la classe qui va les utiliser dans notre code.
Le code ci-dessous vous donne une exception de pointeur null.
Parce que vous êtes à l'aide de
Obj_Student
, mais vous avez oublié d'initialiser comme dans lacorriger le code indiqué ci-dessous:
Il est tout simplement inapproprié d'utiliser le mot "non initialisé" ici. L'exemple que vous avez indiqué est en fait "initialisé", et il est initialisé avec la valeur null. Pour les variables non initialisées, le compilateur va se plaindre de vous.
Un NPE peut être un indicateur que vous êtes en utilisant un non initialisée champ. Il peut être un indicateur que vous faites d'autres choses. Réduire à une seule cause de ce genre ne pas aider quelqu'un à résoudre des NPE problèmes ... si la cause réelle n'est pas celle-ci.
OriginalL'auteur
En Java, tout est dans la forme d'une classe.
Si vous souhaitez utiliser n'importe quel objet, alors vous avez deux phases:
Exemple:
Object a;
a=new Object();
De même pour le tableau concept
Item i[]=new Item[5];
i[0]=new Item();
Si vous ne vous donnez pas la section initialisation puis le
NullpointerException
surviennent.Une NullPointerException se produit souvent lors de l'appel de méthode d'une instance.Par exemple, si vous déclarez une référence, mais ne pas le faire pointer vers n'importe quelle instance, NullPointerException va se produire lorsque vous appelez sa méthode. tels que: YourClass ref = null; // ou ref = anotherRef; // mais anotherRef n'a relevé aucun exemple réf.someMethod(); // on va jeter NullPointerException. Généralement le réparer de cette manière: Avant l'appel de la méthode, de déterminer si la référence est nulle. par exemple: si (yourRef != null) { yourRef.someMethod(); }
Ou exception relative à l'utilisation de capture: comme: try { yourRef.someMethod(); } catch (NullPointerException e) { // TODO }
OriginalL'auteur
Dans Java toutes les variables que vous déclarez sont en fait des "références" pour les objets (ou primitives) et non les objets eux-mêmes.
Lorsque vous essayez d'exécuter une méthode de l'objet, la référence de la demande à la vie de l'objet pour l'exécution de cette méthode. Mais si la référence est référence NULL (nothing, zéro, nul, nada) il n'existe aucun moyen de la méthode est exécutée. Ensuite, le moteur d'exécution vous permettent de savoir ce en jetant une NullPointerException.
Votre référence est "pointant" null, "Null -> Pointeur".
L'objet réside dans la mémoire virtuelle de l'espace et la seule façon d'y accéder est d'utiliser
this
références. Prenez cet exemple:Et sur une autre place dans votre code:
Ce une chose importante à savoir lorsqu'il n'y a plus de références à un objet (dans l'exemple ci-dessus, lorsque
reference
etotherReference
à la fois du point de null), alors l'objet est "inaccessible". Il n'y a aucun moyen que nous pouvons travailler avec elle, de sorte que cet objet est prêt à être des ordures collectées, et à un certain point, la machine virtuelle permettra de libérer la mémoire utilisée par l'objet et va allouer de l'autre.OriginalL'auteur
Une autre occurrence d'un
NullPointerException
se produit lorsque l'on déclare un tableau d'objets, puis tente immédiatement de déréférencer des éléments à l'intérieur d'elle.Ce particulier NPE peut être évité si la comparaison ordre est inversé, à savoir, l'utilisation
.equals
sur garanti objet non-null.Tous les éléments à l'intérieur d'un tableau sont initialisés à leur valeur initiale; pour n'importe quel type d'objet tableau, cela signifie que tous les éléments sont
null
.Vous doit initialiser les éléments dans le tableau avant l'accès ou de déréférencement.
1. NullPointerException est une RuntimeException, qui signifie apparaît lorsque votre programme est en cours d'exécution, vous ne serez pas au moment de la compilation.! :(, mais la plupart des IDE vous aider à découvrir cette. 2. Minimiser l'utilisation du mot-clé 'null', dans les instructions d'affectation. 🙂 url de Référence:
Je suis complètement confus quant à pourquoi vous avez fait ce commentaire... Mais à votre deuxième point, un modèle avant de l'
Optional
était de retourner la valeur null. Le mot-clé est très bien. Sachant comment se prémunir contre il est essentiel. Cette offre commune apparition de celui-ci et les moyens de l'atténuer.NullPointerException est un exécution exception qui n'est pas recommandé pour l'attraper, mais au lieu de l'éviter.
À quel moment dois-je même jusqu'à suggérer qu'il devrait être pris?
OriginalL'auteur