Qu'est-ce que NullPointerException et comment y remédier ?
P粉649990273
P粉649990273 2023-08-23 10:22:08
0
2
597
<p>Que sont les exceptions de pointeur nul (<code>java.lang.NullPointerException</code>) et quelle en est la cause ? </p> <p>Quels méthodes/outils peuvent être utilisés pour déterminer la cause afin d'éviter que l'exception ne provoque la fin prématurée du programme ? </p>
P粉649990273
P粉649990273

répondre à tous(2)
P粉252116587

NullPointerException 是当您尝试使用指向内存中任何位置 (null) 的引用时发生的异常,就像引用对象一样。对空引用调用方法或尝试访问空引用的字段将触发 NullPointerException。这些是最常见的,但 中列出了其他方法NullPointerExceptionpage javadoc.

L'exemple de code le plus rapide auquel je puisse penser pour illustrer une NullPointerException est probablement :

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

dans main 内的第一行,我显式地将 Object 引用 obj 设置为 null 。这意味着我有一个引用,但它没有指向任何对象。之后,我尝试通过调用该引用的方法来将该引用视为指向一个对象。这会导致 NullPointerException car il n'y a pas de code à exécuter à l'emplacement pointé par la référence.

(C'est une question technique, mais je pense que cela vaut la peine de le mentionner : une référence à null n'est pas la même chose qu'un pointeur C pointant vers un emplacement mémoire invalide. Un pointeur nul ne pointe nulle part , ce qui est la même chose comme pointant vers un emplacement qui s'avère être invalide. Différence subtile)

P粉593536104

Il existe deux principaux types de variables en Java :

  1. Primitives : Variables contenant des données. Si vous souhaitez manipuler les données de la variable d'origine, vous pouvez manipuler la variable directement. Par convention, les types primitifs commencent par une lettre minuscule. Par exemple, les variables de type intchar sont des primitives.

  2. Référence : Une variable contenant l'adresse mémoire d'un Objet, c'est-à-dire une variable qui 对象内存地址的变量,即引用对象的变量代码>.如果您想要操作引用变量引用的Object,则必须取消引用它。取消引用通常需要使用 . 访问方法或字段,或使用 [ 索引数组。按照惯例,引用类型通常用以大写字母开头的类型来表示。例如,Objectréférence à un

    Objet
  3. code> Si vous souhaitez faire fonctionner le . >Objet référencé par le code variable de référence>, vous devez le
déréférence

le. Le déréférencement nécessite généralement l'utilisation de . pour accéder à une méthode ou à un champ, ou de [ pour indexer un tableau. Par convention, les types référence sont généralement représentés par le type commençant par une lettre majuscule. Par exemple, les variables de type Object sont des références. int

Considérez le code suivant, où vous déclarez une variable

rawx 指定任何值,而我们正在尝试使用 x 的值来指定 y de type

mais ne l'initialisez pas :

int x;
int y = x + x;
Ces deux lignes feront planter le programme car il n'y a pas de >. Toutes les primitives doivent être initialisées à des valeurs utilisables avant de pouvoir être manipulées. null,这意味着“我没有引用任何东西”。如果您以这种方式显式设置引用变量,则可以在引用变量中获取 null 值,或者引用变量未初始化并且编译器不会捕获它(Java 会自动将该变量设置为 null Maintenant, les choses deviennent intéressantes.

RéférencesLes variables peuvent être définies sur null, ce qui signifie "Je ne fais référence à rien ". Si vous définissez explicitement une variable de référence de cette manière, vous pouvez obtenir une valeur null dans la variable de référence, ou la variable de référence n'est pas initialisée et le compilateur ne l'attrape pas (Java définit automatiquement la variable à null). NullPointerException

Si vous définissez une variable de référence sur null, explicitement ou automatiquement via Java, et que vous essayez

de la déréférencer NullPointerException, vous obtiendrez un

.

se produit généralement lorsque vous déclarez une variable mais que vous ne créez pas et n'attribuez pas l'objet à la variable avant d'essayer d'utiliser le contenu de la variable

(NPE). Vous faites donc référence à quelque chose qui n’existe pas réellement. num的变量,但它实际上还不包含引用值。由于您还没有说出要指向什么,Java 将其设置为 null

Utilisez le code suivant :

Integer num;
num = new Integer(10);
new关键字用于实例化(或创建)一个Integer类型的对象,引用变量num 被分配给该 IntegerLa première ligne déclare un fichier nommé .

num,您将得到一个NullPointerException。在最简单的情况下,编译器会捕获问题并让您知道“num 可能尚未初始化Deuxième ligne,

objet.

Si vous essayez de déréférencer num avant de créer l'objet,

obj,而是假设它是在调用 doSomething() vous obtiendrez un

. Dans le cas le plus simple, le compilateur détectera le problème et vous indiquera "num n'a peut-être pas été initialisé", mais parfois vous pouvez écrire du code qui ne crée pas directement l'objet. 🎜 🎜Par exemple, vous pourriez avoir la méthode suivante : 🎜
public void doSomething(SomeObject obj) {
   // Do something to obj, assumes obj is not null
   obj.myMethod();
}
🎜Dans ce cas, vous ne créez pas l'objet qui a été créé avant la méthode 🎜. Notez que la méthode peut être appelée comme ceci : 🎜
doSomething(null);

Dans ce cas, objnull,并且语句 obj.myMethod() 将抛出 NullPointerException >.

Si la méthode a l'intention d'effectuer une opération sur l'objet transmis comme la méthode ci-dessus, lancer NullPointerException est approprié car il s'agit d'une erreur du programmeur et le programmeur a besoin de ces informations à des fins de débogage.

En plus des NullPointerException 异常之外,您还可以检查方法参数中的 null exceptions levées en raison de la logique de la méthode, vous pouvez également vérifier la valeur

dans les paramètres de la méthode et lancer explicitement le NPE en ajoutant quelque chose comme : près du début de la méthode suivante :

// Throws an NPE with a custom error message if obj is null
Objects.requireNonNull(obj, "obj must not be null");
Notez qu'il serait utile d'indiquer explicitement quel nullobjet ne peut pas être dans le message d'erreur. Les avantages de cette validation sont que 1) vous pouvez renvoyer votre propre message d'erreur plus clair, 2) pour le reste de la méthode, vous savez qu'à moins que obj ne soit réaffecté, il n'est pas nul et peut être déréférencé en toute sécurité

. Alternativement, dans certains cas, le but de la méthode n'est pas seulement d'opérer sur l'objet transmis, donc un paramètre vide peut être acceptable. Dans ce cas, vous devez vérifier le paramètre nuldoSomething() et vous comporter différemment. Vous devez également expliquer cela dans la documentation. Par exemple,

peut s'écrire :

/**
  * @param obj An optional foo for ____. May be null, in which case
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj == null) {
       // Do something
    } else {
       // Do something else
    }
}
Enfin, Comment utiliser les traces de pile pour identifier les exceptions et les causes

Le sonar doté de capacités de recherche de bogues peut détecter les NPE. 一个>Le sonar peut-il capturer dynamiquement les exceptions de pointeur nul causées par JVM

Maintenant, Java 14 ajoute une nouvelle fonctionnalité de langage pour afficher la cause première de NullPointerException. Cette fonctionnalité linguistique fait partie de SAP Business JVM depuis 2006.

En Java 14, voici un exemple de message d'exception NullPointerException :

NullPointerExceptionListe des situations qui provoquent que

se produise

NullPointerExceptionVoici toutes les situations où

se produit comme directement* mentionné par la spécification du langage Java :
  • Accédez (c'est-à-dire obtenez ou définissez) le champ instance
  • d'une référence nulle. (Les champs statiques ne comptent pas !)
  • Appelez la méthode instance
  • d'une référence nulle. (Les méthodes statiques ne comptent pas !)
  • 抛出空值;
  • Accédez aux éléments du tableau vide.
  • synchronized (someNullReference) { ... }Sync sur null -
  • NullPointerExceptionTout opérateur entier/virgule flottante peut être lancé si l'un de ses opérandes est une référence nulle encadrée
  • NullPointerExceptionLa conversion de déballage augmente
  • si la valeur encadrée est nulle.
  • super 会引发 NullPointerExceptionAppeler super sur une référence nulle augmente
  • . Si vous êtes confus, il s'agit d'appels de constructeurs de superclasses qualifiés :
class Outer {
    class Inner {}
}
class ChildOfInner extends Outer.Inner {
    ChildOfInner(Outer o) { 
        o.super(); // if o is null, NPE gets thrown
    }
}
  • for (element : iterable)Utilisez

    loop pour parcourir une collection/un tableau vide. 🎜
  • switch (foo) { ... }(无论是表达式还是语句)在 foo 时可以抛出 NullPointerException est vide.

  • foo.new SomeInnerClass()foo 为 null 时抛出 NullPointerException.

  • name1::name2primaryExpression::name 形式的方法引用在以下情况下求值时会抛出 NullPointerException name1 或 primaryExpression est évalué à null.

    La note de JLS indique que someInstance.someStaticMethod() 不会抛出 NPE,因为 someStaticMethod 是静态的,但 someInstance:: someStaticMethod lance toujours du NPE !

  • * Attention, JLS peut aussi indirectement parler beaucoup de NPE.

    Derniers téléchargements
    Plus>
    effets Web
    Code source du site Web
    Matériel du site Web
    Modèle frontal
    À propos de nous Clause de non-responsabilité Sitemap
    Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!