为什么 Eclipse 说 null 是一种原始类型?

2022-09-03 16:00:04

我在Eclipse Mars中写了这行代码,用于混乱的目的:

null.toString();

我收到以下编译器错误消息:

无法在基元类型 null 上调用 toString()

这是非常奇怪的,因为不是基元类型也不是对象引用,如这里所解释的那样:null是一个对象吗?null

所以,为了确定,我试图编译这样奇怪的代码行,我得到了这个结果:javac

NullTest.java:3: <nulltype> cannot be dereferenced

   null.toString();
       ^  
1 error

有人知道为什么Eclipse会给出这种(IMO)误导性的编译器错误消息吗?


答案 1

由于 null 类型是 的子类型,因此可以调用 上的方法。ObjectObjectnull

但是,按照该逻辑,由于 null 类型是每个引用类型的子类型,因此应该允许我们调用 上任何类/接口的任何方法。那将是一团糟。null

从语法上讲,首先应该识别为方法调用表达式,因为它是表达式。然后,确定要搜索该方法的类/接口,JLSnull.toString()nullPrimarytoString

...如果 T 是类或接口类型,则要搜索的类或接口为 T;如果 T 是类型变量,则为 T 的上限

如果 T 不是引用类型,则为编译时错误。

T是此处的空类型;它不是类类型、接口类型或类型变量,因此此步骤应该会失败。但是,它是否因为 T 不是引用类型而失败?

空类型是引用类型吗?JLS

类型...分为两类:基元类型和引用类型

数值类型为....

引用类型包括类类型、接口类型、[类型变量]和数组类型。[句号!

还有一个特殊的空类型

根据您对文本的分析,null 类型可能是也可能不是引用类型。这通常并不重要。这只是一个分类问题。但它会导致混淆,例如在这种情况下 - 失败是因为不是“正确”的引用类型,编译器错误地推断出它必须是基元类型。T


答案 2

没有理由。

通常,eclipse分析字节码,并且由于某种原因有两个字节码语句,一个定义和一个调用。因为您只能调用对象,所以 eclipse 假定声明必须声明一个基元。null.toString()toString

您可以编写 Bugreport,但请考虑错误消息国际化可能带来的开销。