为什么这不会抛出NullPointerException? [英] Why is this not throwing a NullPointerException?

查看:153
本文介绍了为什么这不会抛出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.这可能不是地址,只是用来简化这里的事情。 地址通常 Object#hashCode()中给出的奇怪的十六进制表示,但这是依赖于实现的。 1

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 Object#hashCode(), but this is implementation-dependent.1

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆