为什么这不会抛出NullPointerException? [英] Why is this not throwing a NullPointerException?
问题描述
以下代码的澄清:
StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample.append("B");
System.out.println(sample);
这将打印 B
以便证明 sample
和 referToSample
对象引用相同的内存引用。
This will print B
so that proves sample
and referToSample
objects refer to the same memory reference.
StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
sample.append("A");
referToSample.append("B");
System.out.println(referToSample);
这将打印 AB
,这也证明了相同。
This will print AB
that also proves the same.
StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample = null;
referToSample.append("A");
System.out.println(sample);
显然这会抛出 NullPointerException
因为我是试图在空引用上调用追加
。
Obviously this will throw NullPointerException
because I am trying to call append
on a null reference.
StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample = null;
sample.append("A");
System.out.println(sample);
所以这是我的问题,为什么最后一个代码示例没有抛出 NullPointerException
因为我从前两个例子中看到和理解的是,如果两个对象引用同一个对象,那么如果我们更改任何值,那么它也会反映到其他对象,因为它们都指向相同的内存引用。那么为什么这条规则不适用于此?如果我将 null
分配给referToSample,那么sample也应该为null并且它应该抛出一个NullPointerException,但它不会抛出一个,为什么?
So Here is my question, why is the last code sample not throwing NullPointerException
because what I see and understand from first two examples is if two objects referring to same object then if we change any value then it will also reflect to other because both are pointing to same memory reference. So why is that rule not applying here? If I assign null
to referToSample then sample should also be null and it should throw a NullPointerException but it is not throwing one, why?
推荐答案
null
通过全局销毁该对象,分配不会更改 value 。这种行为会导致难以追踪的错误和违反直觉的行为。它们只会破坏特定的引用。
null
assignments do not change value by globally destroying that object. That kind of behavior would lead to hard-to-track bugs and counterintuitive behavior. They only break that specific reference.
为简单起见,我们假设 sample
points地址12345.这可能不是地址,只是用来简化这里的事情。 地址通常用 1 Object#hashCode()
中给出的奇怪的十六进制表示,但这是依赖于实现的。
For simplicity, let's say that sample
points to address 12345. This is probably not the address, and is only used to make things simple here. The address is typically represented with the weird hexadecimal given in 1Object#hashCode()
, but this is implementation-dependent.
StringBuilder sample = new StringBuilder(); //sample refers to
//StringBuilder at 12345
StringBuilder referToSample = sample; //referToSample refers to
//the same StringBuilder 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 StringBuilder at 12345
System.out.println(sample);
从标有的行中查看图表
当时对象的图表如下:
From the lines marked See diagram
the diagrams of the objects at that time are as follows:
图1:
[StringBuilder sample] -----------------> [java.lang.StringBuilder@00012345]
↑
[StringBuilder referToSample] ------------------------/
图2:
[StringBuilder sample] -----------------> [java.lang.StringBuilder@00012345]
[StringBuilder referToSample] ---->> [null pointer]
图2显示取消 referToSample
不会将示例
的引用中断为 00012345
中的StringBuilder。
Diagram 2 shows that annulling referToSample
does not break the reference of sample
to the StringBuilder at 00012345
.
1 GC考虑因素令人难以置信。
1GC considerations make this implausible.
这篇关于为什么这不会抛出NullPointerException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!