Pourquoi ne lance-t-il pas une exception NullPointerException?

Nead clarification pour le code suivant:

SsortingngBuilder sample = new SsortingngBuilder(); SsortingngBuilder referToSample = sample; referToSample.append("B"); System.out.println(sample); 

Cela affichera B afin de prouver que les objects sample et referToSample font référence à la même référence de mémoire.

 SsortingngBuilder sample = new SsortingngBuilder(); SsortingngBuilder referToSample = sample; sample.append("A"); referToSample.append("B"); System.out.println(referToSample); 

Cela va imprimer AB qui prouve également la même chose.

 SsortingngBuilder sample = new SsortingngBuilder(); SsortingngBuilder referToSample = sample; referToSample = null; referToSample.append("A"); System.out.println(sample); 

Evidemment, cela va lancer une NullPointerException parce que j’essaie d’appeler append sur une référence null.

 SsortingngBuilder sample = new SsortingngBuilder(); SsortingngBuilder referToSample = sample; referToSample = null; sample.append("A"); System.out.println(sample); 

Alors voici ma question, pourquoi le dernier exemple de code ne lance pas NullPointerException car ce que je vois et comprends des deux premiers exemples est que si deux objects se référant au même object alors si nous changeons une valeur alors à la même référence mémoire. Alors, pourquoi cette règle ne s’applique pas ici? Si j’atsortingbue null à referToSample, alors sample devrait également être null et il devrait lancer une exception NullPointerException mais il n’en lance pas une, pourquoi?

null affectations null ne changent pas de valeur en détruisant globalement cet object. Ce type de comportement conduirait à des bogues difficiles à suivre et à un comportement contre-intuitif. Ils ne font que casser cette référence spécifique.

Par souci de simplicité, supposons que les points d’examen s’adressent à 12345. Ce n’est probablement pas l’adresse et elle sert uniquement à simplifier les choses ici. L’adresse est généralement représentée avec l’hexadécimal bizarre donné dans Object#hashCode() , mais cela dépend de l’implémentation. 1

 SsortingngBuilder sample = new SsortingngBuilder(); //sample refers to //SsortingngBuilder at 12345 SsortingngBuilder referToSample = sample; //referToSample refers to //the same SsortingngBuilder at 12345 //SEE DIAGRAM 1 referToSample = null; //referToSample NOW refers to 00000, //so accessing it will throw a NPE. //The other reference is not affected. //SEE DIAGRAM 2 sample.append("A"); //sample STILL refers to the same SsortingngBuilder at 12345 System.out.println(sample); 

À partir des lignes marquées See diagram les diagrammes des objects à ce moment-là sont les suivants:

Schéma 1:

 [SsortingngBuilder sample] -----------------> [java.lang.SsortingngBuilder@00012345] ↑ [SsortingngBuilder referToSample] ------------------------/ 

Diagramme 2:

 [SsortingngBuilder sample] -----------------> [java.lang.SsortingngBuilder@00012345] [SsortingngBuilder referToSample] ---->> [null pointer] 

Le diagramme 2 montre que l’annulation de referToSample ne casse pas la référence de l’ sample au SsortingngBuilder à 00012345 .

1 Les considérations du GC rendent cela peu plausible.

Au départ, c’était comme vous l’avez dit, referToSample faisait référence à l’ sample comme indiqué ci-dessous:

1. Scénario 1:

referToSample fait référence à l'échantillon

2. Scénario1 (suite):

referToSample.append (

  • Ici, comme referToSample faisait référence à sample , il a donc ajouté “B” pendant que vous écrivez

    referToSample.append("B")

Même chose dans le scénario 2:

Mais, en 3. Scénario 3: comme le dit l’hexafraction,

Lorsque vous atsortingbuez la valeur null à referToSample quand il faisait référence à l’ sample il ne referToSample pas la valeur à la place, il ne faisait que casser la référence de l’ sample et maintenant il ne pointe nulle part . comme indiqué ci-dessous:

quand referToSample = null

Maintenant, comme referToSample pointe nulle part , alors pendant que vous faites referToSample.append("A"); à referToSample.append("A"); il ne serait pas avoir de valeurs ou de référence où il peut append A. Donc, il lancerait NullPointerException .

MAIS l’ sample est toujours le même que vous l’aviez initialisé avec

SsortingngBuilder sample = new SsortingngBuilder(); donc il a été initalisé, donc maintenant il peut append A, et ne lancera pas NullPointerException

En bref: vous affectez null à une variable de référence, pas à un object.

Dans un exemple, vous modifiez l’ état d’un object auquel font référence deux variables de référence. Lorsque cela se produit, les deux variables de référence refléteront le changement.

Dans un autre exemple, vous modifiez la référence affectée à une variable, mais cela n’a aucun effet sur l’object lui-même, et la deuxième variable, qui fait toujours référence à l’object d’origine, ne remarquera aucun changement d’état de l’object.


Donc en ce qui concerne vos “règles” spécifiques:

Si deux objects se rapportant au même object, alors, si nous modifions une valeur, cela se répercutera également sur les autres car les deux pointent vers la même référence de mémoire.

Encore une fois, vous faites référence à la modification de l’ état de l’object auquel les deux variables font référence.

Alors, pourquoi cette règle ne s’applique pas ici? Si j’atsortingbue null à referToSample alors l’échantillon devrait aussi être nul et il devrait lancer nullPointerException mais il ne lance pas, pourquoi?

Encore une fois, vous modifiez la référence d’une variable qui n’a absolument aucun effet sur la référence de l’autre variable.

Ce sont deux actions complètement différentes et aboutiront à deux résultats complètement différents.

Voir ce schéma simple:

diagramme

Lorsque vous appelez une méthode sur referToSample , alors [your object] est mis à jour et affecte donc aussi l’ sample . Mais quand vous dites referToSample = null , alors vous changez simplement à quoi referToSample fait référence .

Ici, «sample» et «referToSample» font référence au même object. C’est le concept de pointeur différent qui accède au même emplacement de mémoire. Assigner une variable de référence à null ne détruit pas l’object.

  referToSample = null; 

signifie que referToSample ne pointe que sur null, que l’object rest identique et que d’autres variables de référence fonctionnent correctement. Donc, pour ‘sample’ qui ne pointe pas vers null et a un object valide

  sample.append("A"); 

fonctionne bien Mais si nous essayons d’append null à ‘referToSample’, cela affichera NullPointException. C’est,

  referToSample .append("A");-------> NullPointerException 

C’est pourquoi vous avez NullPointerException dans votre troisième extrait de code.

Chaque fois qu’un nouveau mot-clé est utilisé, il crée un object au tas

1) SsortingngBuilder sample = new SsortingngBuilder ();

2) SsortingngBuilder referToSample = sample;

Dans 2) la référence de referSample est créée sur le même échantillon d’object

ainsi referToSample = null; Nulling Seule la référence referSample ne donnant aucun effet à sample, c’est pourquoi vous ne recevez pas d’exception de pointeur NULL grâce à la récupération de place de Java

Simplement facile, Java n’a pas de référence par passe, il ne fait que passer la référence d’object.