null是否为Object?


119

ObjectJava中是否为null ?


41
不,不是,对于那些想知道为什么这样的问题的人,有些语言中null确实是像任何对象一样的对象,例如Ruby。
JRL

7
在对类型非常细致的Scala中,有一个类型Null(实际上是特征)具有一个实例null
卡尔·斯莫特里兹

1
@JRL:出于好奇,我不知道这会如何影响JRuby的工作……(我对这种实现水平还不十分了解,无法确定。)
Benjamin Oakes 2010年

要添加到@ JRL的评论- Ruby的粗糙相当于nullnil,这是一个实例NilClass
艾略特·赛克斯

或javascript,其中null instanceof Object为false,但typeof(null)返回'object'。在这种情况下是物体吗?谁知道。
唐·哈奇

Answers:


166

如果Object为null,它将支持java.lang.Object诸如的方法equals()。但是,事实并非如此-对null的任何方法调用都会导致NullPointerException

这是Java语言规范在该主题上必须说的:

还有一个特殊的null类型,即表达式null的类型,它没有名称。由于空类型没有名称,因此无法声明空类型的变量或将其强制转换为空类型。空引用是空类型表达式的唯一可能的值。空引用始终可以转换为任何引用类型。在实践中,程序员可以忽略null类型, 而只是假装null只是可以是任何引用类型的特殊文字。

我认为这可以归结为“ null is special”。


1
因此,Java中的对象只有等于或子类时才是对象java.lang.Object。实际上-是的。您无法创建不是java.lang.Object的子类的类,但我从未从更哲学的角度考虑它
Andreas Dolk,2009年

奇怪的是,关于所有内容的API文档NullPointerException都提到了» null对象«... :),但是然后,也可以谈论»空指针«…
Lumi 2014年

您说:“空引用始终可以转换为任何引用类型”。那么,我们是否可以在具有对象引用(返回)类型的方法中返回null(如果允许,则为typecasted)?
Srichakradhar 2014年

1
@Srichakradhar:是的,我们可以!通过在代码中进行尝试,比在这里询问更容易找到。
Michael Borgwardt 2014年

1
“空引用是空类型表达式的唯一可能的值”。现在该阅读规格文档。:)
sofs1 '16

32

根据Java 规范null是一种可以分配给对象变量的类型(如注释中所述的值)。但是,您无法实例化或创建这种类型的变量,必须使用null编译器提供的文字。


8
null是类型和值。
约阿希姆·绍尔

5
显然,该null名称是该null类型的“实例” 。
斯特拉格

null不是变量,而是文字:JLS,3.10.7。空的文字
Gerold Broser

Re“ null是可以分配的类型 ”:1)null(在代码中)是null文字,不是null类型 2)通常不能在Java中将类型分配给变量,请参见JLS 4.1:“ 有[...可以存储在变量中的两种数据值:原始值(§4.2)和引用值(§4.3)。 这是可以通过文字分配的空引用null。...继续...
Gerold Broser

3)对象中的“ 对象变量 ”相比,类变量,一般不指的类型,但以寿命。引用类型时,通常称为引用类型的变量,或者简称为引用(类型)变量。我知道Java API中有4种类型,它们公开了实例/对象变量(可能还有更多):具有及其length子类的数组java.awt.geom.Point2D
Gerold Broser



12

空是缺少对象。


但是null类型可分配给每个引用类型。
Tom Hawtin-大头钉

没有“空类型”。null是非基本表达式的特定值(即引用;据我所知,Java中也没有“引用类型”)。
Tommy McGuire

3
汤米:JLS 4.1:“还有一个特殊的null类型,即表达式null的类型,它没有名称。”


12

JRL写道:

不,这不对, ...

通常,这取决于您从哪里看,谁会相信更多。

根据JLS,是的。特别是如果您将问题改写为:“是null文字类型Object吗?”。除了上面迈克尔·伯格沃德(Michael Borgwardt)引用的JLS 4.1

参见JLS 3.10.7

空文字始终是空类型。

JLS 4.10

类型T的子类型都是U类型,因此T是U的超类型,并且是null类型。

JLS 4.10.2

空类型的直接超类型是除空类型本身之外的所有引用类型

[我的重点。]

根据Eclipse 2019-09的编译器,它不是

true.toString();  // Cannot invoke toString() on the primitive type boolean
null.toString();  // Cannot invoke toString() on the primitive type null

根据OpenJDK 12.0.1,javac 它是

true.toString();  // error: boolean cannot be dereferenced
null.toString();  // error: <null> cannot be dereferenced

尖括号表示那null不是基本类型。根据JLS 4.1

Java编程语言中有两种类型:基本类型(...)和引用类型(...)。

如果不是一个,那就是另一个。


克劳迪乌写道:

null有点丑陋。

互惠生,null是美丽的。您会建议使用什么作为参考类型变量的默认值?任意位组合?欢迎访问冲突,甚至更糟的是指针地狱!


约阿希姆·绍尔(Joachim Sauer)写道:

null是类型和值。

实际上,有三个null结合使用的项(另请参见JLS 3.10.7):

  1. (否则为未命名)null类型
  2. null 文字
  3. 空引用值。(通常缩写为null值或简称为null。)

(1)注意,根据上面引用的JLS 4.10.2null类型不仅对接口而且对类都使用多重继承。众所周知,对于我们的应用程序程序员而言,这是不可能的。

(2)空字面量可以想象为一个变量,定义为:

JVM_global final null_type null = new null_type();

另请注意JLS 3.9

有时会错误地将各种字符序列假定为关键字:

  • null不是关键字,而是null文字(第3.10.7节)。

关于 null instanceof <any type>

考虑到JLS 4.10.2(“ 空类型是每种类型的子类型”)null instanceof <any type>应该被评估为true,不是吗?乍一看,是的,但是JLS 15.20.2给出了见解的答案:

[...] 的结果所述的instanceof操作者true如果该值的的RelationalExpression 不是null [...]。否则结果为false

[我的重点。]

问自己(从应用程序程序员的角度来看)什么更有意义:

  • 给出false并因此表明引用表达式不是我们公开的类型,即表明它未引用对我们有用的任何东西

  • 或给定true,从而通知我们该表达式的值是一个特殊引用,即null引用,它引用一个“对象”,我们不知道该对象甚至不存在,并且是没有名称的特殊null类型,也不会暴露给该对象我们,但是通过null常量,是包含多重继承的任何类型的子类型,并且无论如何都将被忽略?还考虑更实际的示例:

     class Car implements Vehicle {  
     ...
     Vehicle car = null;
     ...
     boolean b = car instanceof Car;  // True? There's not even an instance
     ...                              // which could be of type Car.

这也导致:

为什么instanceof没有适当的方式来谈论null “对象性”的?

叫做instanceofnot sameorsubtypeof。这意味着我们正在将实例的类型与一个类型而不是两个类型进行比较。现在null表示:“没有实例”,如果没有实例,则没有实例的类型。很明显,什么都没有做应该导致false

或在“更多”的真实世界示例中:

  • 我手上有»Big Apple«(=参考类型名称)的真实尺寸的苹果(=参考类型)图片写)。
  • 有一张桌子(= heap我面前)。
  • 如果桌子上有一个苹果(= instance),则有一根绳子(= reference连接)。
  • 我握住这根绳子的另一端(=参考变量)。
  • 我沿着绳索追踪苹果,并将其与我的图片(= instanceof)进行比较。
  • 如果苹果的大小等于或大于图片,则文字“大苹果”适用于它(= true)。
  • 如果较小,则不是(= false)。
  • 如果表上没有苹果(= no instance),因此不存在任何连接线(= null),则书写也不适用(= false)。原因如下:没有苹果大苹果?不,这不对。


正如迈克尔所总结的:“零是特别的”。


2
苹果和空?你不怕打官司吗?:)
的GaborLipták

9

不,它不是类的实例,也不是类。它是对任何事物的引用。

编辑:尚未阅读规格,因此上述内容可能不是100%准确。


5

如Java语言规范的4.1类型和值的种类中所述,null是一种具有一个值的类型,该值是null引用(并由文字表示null):

还有一个特殊的null类型,即expression的类型null,它没有名称。由于空类型没有名称,因此无法声明空类型的变量或将其强制转换为空类型。空引用是空类型表达式的唯一可能的值。空引用始终可以转换为任何引用类型。在实践中,程序员可以忽略null类型,而只是假装这null只是可以是任何引用类型的特殊文字。

但是,您可能想了解有关Null对象模式的信息(我不建议这样做)。有关此模式的更多信息,请参见C2 WikiWikipedia



4

不,不是一个对象,因为null的instanceof对象将始终返回false,并且只有一个null,而不是每个类一个。


3
实际上,null instanceof <anytype>也会返回false
孟买

4

根据Java规范

还有一个特殊的null文字可用作任何引用类型的值。可以将null分配给任何变量,原始类型的变量除外。除了测试空值的存在之外,您几乎无能为力。因此,在程序中经常使用null作为标记,以指示某些对象不可用。


4

Java通过引用处理对象。Null是Java的OO-ness的细目,因为它使您降至OO级以下。不,它不是对象,它是引用的VALUE。它与对象范例无关,而是与启用对象的Java管道有关。


3

null为的实例 java.lang.Object?没有。

null是一个对象吗?取决于“ ” 的定义。


2
Object foo = null;
System.out.println(foo.toString()); 

第一行显示null可以分配给type Object,但是第二行将显示它肯定不是an Object,最终导致ajava.lang.NullPointerException


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.