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 1 Object#hashCode()
, mais cela dépend de l’implémentation.
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:
2. Scénario1 (suite):
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:
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:
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.