1
votes

Objets et exceptions de pointeur nul

Voici donc ma question: dans mon code, j'ai créé un objet ob , et j'ai créé un nœud temporaire juste pour le pointer vers le nœud racine.Ainsi, lorsque j'ai imprimé les données strong> pour temp , comme je m'y attendais, j'ai eu NullPointerException. Mais après avoir assigné des données au nœud racine, J'ai de nouveau imprimé des données pour le nœud temporaire cette fois, je m'attendais à une sortie identique aux données du nœud racine, mais à la place, j'ai à nouveau reçu NullPointerException.

Pourquoi cela se produit-il? Le nœud temporaire n'est-il pas juste en train de pointer (Ouais! Ouais! Il n'y a pas de pointeurs en java).

Voici le code

    import java.util.Scanner;

class abc
{
    class Node
    {
        int data;
        Node next;
        Node(int data)
        {
            this.data=data;
            this.next=null;
        }
    }
    Node root=null;

    void add(int data)
    {
        Node new_node=new Node(data);
        if(root==null)
            root=new_node;
        else
        {
            new_node.next=root;
            root=new_node;
        }
    }

    public static void main(String ar[])
    {
        Scanner sc=new Scanner(System.in);
        abc ob=new abc();
        Node temp=ob.root;
        try {
            System.out.println(temp.data);
        }
        catch (NullPointerException ex)
        {
            System.out.println("Null");
        }
        while(sc.hasNextInt())
            ob.add(sc.nextInt());   //add method is used to add elements in linked list
        //System.out.println(temp.data);

    }

} 

Et voici classe de nœuds.

 class Node
{
    int data;
    Node next;
    Node(int data)
    {
        this.data=data;
        this.next=null;
    }
}

N'hésitez pas à me demander si vous ne comprenez pas mon code Et, veuillez pardonner mon anglais.

Code complet

 abc ob=new abc();
    Node temp=ob.root;
    try {
        System.out.println(temp.data);
    }
    catch (NullPointerException ex)
    {
        System.out.println("Null");
    }
    while(sc.hasNextInt())
        ob.add(sc.nextInt());   //add method is used to add elements in linked list
    System.out.println(temp.data);


6 commentaires

D'après ce que je vois, le problème vient de la classe abc . Pouvez-vous poster le code?


Alors, que contient ob après avoir appelé la méthode add dessus? Veuillez vider le contenu.


@Louis Salut Louis Je viens de modifier ma question. Vérifie s'il te plaît.


@arkascha Je viens de modifier ma question, veuillez la vérifier


@Aniket Saxena J'ai mis à jour ma réponse en fonction du nouveau code que vous avez publié. Vérifiez-le. :)


Merci pour le retour rapide! Et bienvenue pour augmenter les privilèges :-)


4 Réponses :


0
votes

Ici: ob.add (sc.nextInt ()); vous manipulez un objet "parent", donc l'attente, que dans child il n'y aura pas de null < / code> n'est pas justifié. En regardant la définition de la classe Node , il n'a aucune idée de l'existence de la racine .

P.S .: Le code semble manquer certaines parties. Par exemple, je n'ai aucune idée de ce qu'est abc () .


1 commentaires

La classe Node n'a pas besoin de connaître une propriété root . Vous manquez lire le code.



0
votes

Vous obtenez une NullPointerException car vous n'avez jamais appelé la méthode add et donc ob.root est null .

Essayez ce code, cela devrait fonctionner:

 public static void main(String ar[])
    {
        Scanner sc=new Scanner(System.in);
        abc ob=new abc();
        System.out.print("Enter an integer followed by <enter>: ");
        ob.add(sc.readInt());
        Node temp=ob.root;
        try {
            System.out.println(temp.data);
        }
        catch (NullPointerException ex)
        {
            System.out.println("Null");
        }
        while(sc.hasNextInt())
            ob.add(sc.nextInt());   //add method is used to add elements in linked list
        //System.out.println(temp.data);

    } 

PS: Veuillez également noter que selon les conventions de nommage Java , les noms de classe doivent toujours commencez par une lettre majuscule.


5 commentaires

Mais après la mise à jour du nœud racine, je devrais également observer les changements pour le nœud temporaire. Droit?


J'ai mis à jour ma réponse en fonction de votre code. Vérifiez, cela devrait fonctionner.


Oui, Java fonctionne avec des références. Pour mieux comprendre, jetez un œil à cette question: stackoverflow. com / questions / 5160485 / object-vs-reference-in-j‌ ava


Quel est le besoin d'appeler la méthode add. Regardez lorsque j'ai mis à jour les données du nœud racine, la température doit également être mise à jour car elle pointe toujours vers le nœud racine, comment le nœud temporaire est-il nul après la mise à jour du nœud racine.


temp est une référence à un objet . Si vous déclarez temp = ob.root et que ob.root est null , alors vous aurez temp = null . La seule partie du code où vous initialisez root se trouve dans la méthode add , vous devez donc l'appeler d'abord.



1
votes

La variable temp stocke null . null n'est pas un objet. Il n'y a pas de relation entre null dans ob et null dans temp . Par conséquent, lorsque la référence à un nœud est stockée dans ob , la valeur dans temp ne change pas.

Pour plus d'informations sur null , voir ceci .

Vous pouvez stocker un nœud vide dans root . Dans catch block, initialisez root et stockez la même référence dans temp. (Vous pouvez également déclarer un constructeur pour un nœud vide)

void add(int data) {
    if (root.data == 0)
        root.data = data;
    else {
        Node new_node = new Node(data);
        new_node.next = root;
        root = new_node;
    }
}

Dans la méthode add (), vérifiez si root a une valeur et ajoutez une valeur au champ de données de root si elle est vide.

ob.root = ob.new Node(0);
temp = ob.root;


13 commentaires

Ouais, mais quand j'ai mis à jour le nœud racine, la température doit également être mise à jour car elle pointe toujours vers le nœud racine.


null n'est pas un objet et root n'est qu'une variable. Les références concernent des objets et non des variables.


Nulle part. Il avait juste une valeur nulle. Voir la question à laquelle j'ai lié.


D'accord, cela signifie que temp ne pointait pas vers un objet, car null n'est pas un objet. Droit?


Oui, car temp ne stocke aucune référence à un objet.


Maintenant je comprends . Merci les gars . Comment clôturer cette question.


Ce code lancera une exception si root n'est pas initialisé avant d'appeler la méthode add . @Aniket Saxena Avez-vous testé ce code avant d'accepter la réponse?


Edit: racine initialisée dans le bloc catch afin que Null soit imprimé lorsqu'aucune valeur n'a été entrée.


Il peut y avoir de nombreuses façons d'initialiser root en fonction de la situation.


@Louis root est une variable d'instance donc elle fonctionnerait également correctement.


@Hammad Malik Non, bacause à l'instruction root.data == 0 si root est nul, vous essayez d'accéder à une propriété de null ( null.data ) et il lancera une exception. Cela ne fonctionnera pas si root est null .


root n'est pas nul. Une référence à un nœud y est stockée lorsqu'un objet de classe abc est créé.


Dans l'article édité, il y aurait une NullPointerException pour que le bloc catch soit exécuté. Dans le message avant l'édition, root n'était pas nul donc il n'y avait pas d'exception.



0
votes

Voici un peu de ce qui se passe

0
nodeSoulutin.abc$Node@6b71769e
null

*********************. changez-le et vous obtiendrez le dernier nœud de votre temp **************

class abc
{
class Node
{
    int data;
    Node next;
    Node(int data)
    {
        this.data=data;
        this.next=null;
    }
}
Node root=new Node(0);
Node root2 = null;

void add(int data)
{
    Node new_node=new Node(data);
    if(root==null)
        root=new_node;
    else
    {
        new_node.next=root;
        root=new_node;
    }
}

public static void main(String ar[])
{
    Scanner sc=new Scanner(System.in);
    abc ob=new abc();
    // the root value for the ob object is null, as you declared in your class
    //while(sc.hasNextInt())
    //  ob.add(sc.nextInt());   
    // Once you have completd the node entries, the last node is what object ob will hold.
    // and the value will be the root node value

    Node temp=ob.root;

    try {
        System.out.println(temp.data);
        System.out.println(ob.root);
        System.out.println(ob.root2);

    }
    catch (NullPointerException ex)
    {
        System.out.println("Null");
    }


}

}

******** *********** Pour montrer la différence d'initialisation **********

public static void main(String ar[])
{
    Scanner sc=new Scanner(System.in);
    abc ob=new abc();
    // the root value for the ob object is null, as you declared in your class
    while(sc.hasNextInt())
        ob.add(sc.nextInt());   
    // Once you have completd the node entries, the last node is what object ob will hold.
    // and the value will be the root node value

    Node temp=ob.root;

    try {
        System.out.println(temp.data);

    }
    catch (NullPointerException ex)
    {
        System.out.println("Null");
    }


}

****** La sortie sera être ****

public static void main(String ar[])
{
    Scanner sc=new Scanner(System.in);
    abc ob=new abc();
    // the value for root (Node object) for the ob object is null, as you declared in your class

    Node temp=ob.root;
    // You have assigned the null value to the temp reference
    // equivalent to saying Node temp = null;
    try {
        System.out.println(temp.data);
        // This doesnt have anything to refer to so throws the exception
    }
    catch (NullPointerException ex)
    {
        System.out.println("Null");
    }
    while(sc.hasNextInt())
        ob.add(sc.nextInt());   //add method is used to add elements in linked list
    //System.out.println(temp.data);

}


7 commentaires

Ouais, mais quand j'ai mis à jour le nœud racine, la température doit également être mise à jour car elle pointe toujours vers le nœud racine.


Le temp ne pointe pas vers le nœud racine, il a la valeur null. Donc il ne peut pas faire ce que vous attendez de lui


J'édite le code, il vous sera donc demandé de créer les nœuds en premier, et le dernier nœud sera conservé dans votre variable temporaire, qui sera imprimée


Mais à des fins d'expérimentation, qu'est-ce qui ne va pas dans mon code. Je ne peux pas comprendre pourquoi le nœud temporaire est également mis à jour lorsque le nœud racine a été mis à jour.Regardez quand j'ai créé un nœud temporaire sans lui attribuer de mémoire, dans ce scénario, cela signifiait que le nœud temporaire peut pointer vers n'importe quel autre objet de nœud. Donc, dans mon code, temp pointait vers le nœud racine pour toujours, lorsque je mets à jour le nœud racine, le nœud temporaire doit également être mis à jour /


Ce que vous voulez peut être réalisé lorsque vous avez une référence à la racine. alors changez Node root = new Node (0); plutôt que Node root2 = null ;, car le premier vous donnera une référence en mémoire tandis que le dernier attribuera la valeur null à la variable. Je mets à jour le code complet pour imprimer la valeur que les deux contiendront.


Ouais, je comprends ce que vous essayiez tous d'expliquer. Comment puis-je fermer cette question. Merci pour votre aide.


Votez pour la seule réponse qui, selon vous, vous a aidé à obtenir une réponse, aucune autre action n'est requise.