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

查看:21
本文介绍了为什么这不抛出 NullPointerException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对以下代码进行澄清:

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

这将打印 B 以便证明 samplereferToSample 对象引用相同的内存引用.

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 因为我试图在一个空引用上调用 append.

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指向地址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);

从标有See diagram的那几行来看,当时的物体图如下:

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 不会破坏 sample00012345 处的 StringBuilder 的引用.

Diagram 2 shows that annulling referToSample does not break the reference of sample to the StringBuilder at 00012345.

1GC 考虑使这难以置信.

1GC considerations make this implausible.

这篇关于为什么这不抛出 NullPointerException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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