Cette question est liée à Pourquoi String.valueOf (null) lève-t-il une NullPointerException?
Considérez l'extrait de code suivant:
public class StringValueOfNull {
public static void main(String[] args) {
String.valueOf(null);
// programmer intention is to invoke valueOf(Object), but instead
// code invokes valueOf(char[]) and throws NullPointerException
}
}
Comme expliqué dans la réponse à la question liée, la surcharge de méthode de Java résout l'invocation ci-dessus en String.valueOf(char[])
, ce qui entraîne à juste titre un NullPointerException
au moment de l'exécution.
Compilé dans Eclipse et javac 1.6.0_17
, Voici la trace de la pile:
Exception in thread "main" Java.lang.NullPointerException
at Java.lang.String.<init>(Unknown Source)
at Java.lang.String.valueOf(Unknown Source)
at StringValueOfNull.main(StringValueOfNull.Java:3)
Notez que la trace de pile ci-dessus ne contient pas les informations [~ # ~] [~ # ~] de la pile: elle le fait [~ # ~] pas [~ # ~] ont la signature complète de la méthode valueOf
! Il dit simplement String.valueOf(Unknown Source)
!
Dans la plupart des situations que j'ai rencontrées, les traces de pile d'exceptions ont toujours la signature complète des méthodes qui se trouvent réellement dans la trace de pile, ce qui bien sûr est très utile pour identifier le problème immédiatement et une raison majeure pour laquelle la trace de la pile (qui est inutile de dire qu'il est plutôt coûteux à construire) est fournie en premier lieu.
Et pourtant, dans ce cas, la trace de la pile n'aide pas du tout . Il a misérablement échoué en aidant le programmeur à identifier le problème.
En l'état, je peux voir 3 façons dont un programmeur peut identifier le problème avec l'extrait ci-dessus:
String valueOf(char[] data)
est bien celle sélectionnéeLa dernière option est probablement la moins accessible, mais bien sûr, c'est la réponse ultime (un programmeur peut mal comprendre la règle de surcharge, IDE peut être bogué, mais les bytecodes disent toujours (?) La vérité sur ce qui est en cours).
Ceci est normalement lié aux informations de débogage manquantes. Vous utilisez probablement JRE (pas JDK), qui n'inclut pas les informations de débogage pour les classes rt.jar. Essayez d'utiliser JDK complet, vous obtiendrez les emplacements appropriés dans la trace de la pile:
Exception in thread "main" Java.lang.NullPointerException
at Java.lang.String.<init>(String.Java:177)
at Java.lang.String.valueOf(String.Java:2840)
at StringValueOfNull.main(StringValueOfNull.Java:3)
Notez que si vous utilisez Ant build et si l'attribut de débogage est défini sur false dans la commande javac, cela peut se produire.
ex: si vous avez besoin d'un emplacement correct dans le jeu de traces debug = true dans Ant build,
<javac verbose="false" srcdir="${src}" destdir="${classdir}" debug="true" includes="**/*.Java">
<classpath refid="compile.classpath" />
</javac>
J'ai eu le même problème, j'utilise le ressort et Apache ant pour une intégration continue.
L'erreur que j'ai eue était dans le fichier build.xml.
Le journal des changements de genre avec un contenu plus précis était:
build.xml avec l'erreur:
<javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes">
<classpath refid="compile.classpath" />
</javac>
build.xml sans erreur:
<javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes" debug="true">
<classpath refid="compile.classpath" />
</javac>
Au sein de la structure, je manquais de courage debug = "true"
J'ai exécuté le code dans Eclipse et j'ai obtenu la sortie suivante,
public class Aloof {
public static void main(String[] args) {
String.valueOf(null);
}
}
Exception in thread "main" Java.lang.NullPointerException
at Java.lang.String.<init>(String.Java:177)
at Java.lang.String.valueOf(String.Java:2840)
at mysql.Aloof.main(Aloof.Java:19)
Si vous incluez la source complète (à partir de JDK), vous pouvez réellement déboguer vers la ligne 177 dans String.Java
Dans Eclipse: Préférences> Java> JRE installés. L'entrée vérifiée doit avoir un chemin à l'intérieur du JDK, par exemple C:\Program Files (x86)\Java\jdk1.7.0_55\jre.
Cela se produit lorsqu'il n'y a pas d'informations de débogage (ligne) dans la source ou lorsque VM est invité à jeter ces informations au moment du chargement de la classe. Puisque vous avez des numéros de ligne, ce n'est pas le paramètre VM mais la classe String
manque des informations de débogage.