Java:为什么NullPointerException没有被称为NullReferenceExceptions?

35

这是一个疏忽吗?还是与JVM有关?


1
因为指针和引用是同一件事。使用哪个代表这个概念的同义词并不重要。 - Val
4个回答

26

Java确实有指针——但是你不能对指针执行指针算术运算。

引自备受推崇的JLS:

Java编程语言中有两种类型:基本类型(§4.2)和引用类型(§4.3)。相应地,可以存储在变量中、作为参数传递、由方法返回和操作的数据值有两种:基本值(§4.2)和引用值(§4.3)。

还有后文

对象是一个类实例数组

引用值(通常只是引用)是指向这些对象的指针,以及一个特殊的空引用,它不引用任何对象。

(强调为他们所述)

因此,要解释一下,如果你写:

Object myObj = new Object();

如果说myObj是一个引用类型的话,它包含了一个引用值,指向新创建的Object本身。因此,如果你将myObj设置为null,实际上是将这个引用值(也就是指针)设置为null。因此,当对该变量进行取消引用操作时,就会合理地抛出NullPointerException异常。

不要担心:这个话题已经被广泛讨论过


2
Java的引用不一定是指向内存中固定地址的指针。Java允许具有诸如复制垃圾收集器等功能的JVM实现,这些功能可以在内存中移动对象。"myObj是一个包含引用值的引用类型..."是正确的,但"...它本身是指向新创建的对象的指针"则不是。Java引用是具有指定语义的抽象类型。Java引用的实现可以使用简单指针,但不是必须的。NullPointerException也可以很容易地被命名为NullReferenceException。 - Clement Cherlin

3
在Java中,他们使用“引用”这个术语来指代动态创建的对象。在以前的语言中,它被称为“指针”。就像面向对象语言中方法的命名已经取代了早期(面向对象和非面向对象)语言中的函数和过程一样。在这种命名或新标准中,没有特别好或不好的地方,这只是命名能够创建以前的动态对象并悬挂在空中(堆空间),并由固定的对象引用(或动态引用也悬挂在空中)引用的现象的另一种方式。新标准(使用方法和引用)的作者特别提到,新标准的实施是为了符合即将推出的规划系统(如UML和UP)的要求,其中面向对象的术语规定使用属性、方法和引用,而不是变量、函数和指针。
现在,您可能认为这只是一个重命名,但那会简化这个过程的描述,并且不会仅限于语言在发展中所经历的漫长道路。方法的性质与过程不同,在类的范围内运行,而过程则在其性质上在全局范围内运行。同样,属性不仅仅是变量的新名称,因为属性是类(及其实例 - 对象)的属性。同样,这里所讨论的引用是不同的,因为它是有类型的,因此它没有指针的典型属性,即原始的对内存单元的引用,因此,引用是基于内存的结构化引用对象。
现在,在Java中,也就是在Java的胃部,底层C代码和Java代码之间存在一个仲裁层(虚拟机)。在该仲裁层中,通过虚拟机执行的引用的底层(裸金属)实现会保护引用不会引用裸金属(没有结构的内存单元)。因此,真相是NullPointerException实际上是Null Pointer Exception,而不仅仅是Null Reference Exception。然而,对于Java环境中的程序员来说,这个真相可能完全无关紧要,因为他/她在任何时候都不会接触到裸金属JVM。

2
我认为答案是我们永远无法真正知道真正的答案。
我怀疑在发布Java 1.0之前的某个时候,有人定义了一个名为“NullPointerException”的类。不管是那个人把名字搞错了,还是术语尚未稳定;即使用术语“引用”而不是“指针”的决定尚未做出。
无论哪种情况,很可能在注意到这种不一致性之前已经无法修复它,否则会破坏向后兼容性。
但这只是猜测。
注1-如果你非常努力地寻找标准Java SE库中的其他小不一致性,你可以找到一些更严重的问题,由于相同的原因无法修复。

1

我猜这可能与JVM是用C++编码有关。除此之外,指针和引用几乎是相似的。你可以说Java中的引用机制是使用C++指针实现的,并且名称为'NullPointerException'的例外允许该实现细节得以展现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接