当前位置: 首页 > 面试题库 >

为什么这不引发NullPointerException?

骆文彬
2023-03-14
问题内容

需要对以下代码进行澄清:

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

这将打印出来,B以便证明samplereferToSample对象引用相同的内存引用。

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

这将打印出来AB,也证明是相同的。

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

显然,这将引发,NullPointerException因为我试图调用append空引用。

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

所以这是我的问题,为什么最后一个代码示例没有抛出,NullPointerException因为我从前两个示例中看到并理解的是,如果两个对象都引用同一个对象,那么如果我们更改任何值,那么它也会反映给另一个对象,因为两个对象都指向相同的内存引用。那么,为什么该规则在这里不适用?如果我将其分配null给ReferToSample,则sample也应该为null,并且应该抛出NullPointerException,但没有抛出一个异常,为什么?


问题答案:

null分配不会通过全局销毁该对象来更改 。这种行为将导致难以跟踪的错误和违反直觉的行为。他们只是打破了具体的 参考

为了简单起见,假设它sample指向地址12345。这可能不是地址,在这里仅用于简化。 该地址 通常
用中给出的怪异十六进制表示 Object#hashCode(),但这与实现有关。
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开始,当时的对象图如下:

图1:

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

图2:

[StringBuilder sample]    -----------------> [java.lang.StringBuilder@00012345]

[StringBuilder referToSample] ---->> [null pointer]

图2显示,废止referToSample不会破坏sample对StringBuilder 的引用00012345

1 GC的考虑使其难以置信。



 类似资料:
  • 问题内容: 有什么不同之处与使得迭代器不会引发异常而引发异常?最后,两者都在修改集合大小。 请在这里忽略多线程。我只是在谈论一个for-each循环和一个迭代器循环。据我所知,for-each循环仅在内部创建迭代器。 我很困惑。 问题答案: 不会抛出,因为这是在迭代时修改集合的 允许 方式。这是什么的Javadoc的说: 从基础集合中移除此迭代器返回的最后一个元素(可选操作)。每次调用next()

  • 问题内容: 为什么这段代码不抛出?它在不使用方法的情况下修改了一段时间,这是唯一安全的删除方法。 如果将替换为,则会得到相同的结果。但是,如果我将列表更改为或只是得到了预期的异常。到底是怎么回事?我正在使用是否相关。 编辑 我找到了以下链接 http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4902078 相关部分是 天真的解决方案是将协同修改

  • 如果我运行deldeldel(“adel”),它会返回一个,但是,adel的长度是4,这意味着最后一个字符串索引是3,为什么str.substring(4,str.length()没有超出范围?

  • 问题内容: 我一直在尝试使用解析文件: 当然,这是我的代码的简化版本,但这足以破坏我的程序。如果删除try-catch块,则会出现一些文件出现此错误的情况: 但是,结果是确定性的,如果文件有效,它将始终有效。如果文件失败,则它总是失败并且总是在同一点失败。 最奇怪的是,我正在使用跟踪来确定是否有任何格式错误的XML破坏了解析器。然后,我隔离导致故障的节点。但是,当我创建一个包含该节点及其几个邻居的

  • 我正在尝试改变我的引导网站中与类“navbar-brand”链接的颜色。无论我如何构造css选择器,我似乎都无法改变文本颜色。但是,我知道css正在加载,因为我可以更改navbar的背景颜色。下面是缩短的代码: 我的index.html: 我的main.css: 最终结果:一个深蓝色条,带有默认navbar附带的灰色文本。谢谢你的帮助。 编辑:这里类似的问题对我没有帮助。我能够改变navbar-n

  • 问题内容: 为什么这段代码没有抛出?看一看: 我不知道! 问题答案: 您为什么不能自己检查一下并抛出异常(如果您要的话)。