为什么null在Java中不是一个对象,如果它可以分配给任何引用类型的话



我的第一个问题是null文本有引用类型吗?我很困惑null是否没有引用类型,或者null文本是否有数据类型,但没有名称。无论哪种方式,null都可以是任何引用类型。如果null可以分配给任何Object类型,为什么null本身不能是对象?在Java中,字符串文字本身就是一个对象。每个引用类型都可以在Java中生成一个Object,那么不应该将其应用于null吗?

不幸的是,在许多关于Java的教程、书籍和其他资源中;对象";以及";变量";以草率的方式使用,这可能会导致与你在问题中描述的内容类似的混乱。

例如,看看这行代码:

String message = "Hello World";

人们经常会说";这里我有一个名为messageString对象,其值为"Hello World〃;。这是错误的,它让初学者认为对象和变量是一样的,对象有名称。

准确的是:;这里有一个名为message的变量,它是对值为"Hello World"String对象的引用。

变量和对象不是一回事。变量*不是对象,它是对对象的引用(它是指向内存中某个对象的指针)。

变量有名称。在上面的代码中,有一个名为message的变量。对象没有名称。

变量和对象之间也不存在一一对应关系。多个变量可以引用同一个对象。

值CCD_ 8是一个特殊值,您可以将其分配给变量*;该变量不涉及对象";。它就像C和C++等语言中的空指针一样。

null说成是一个物体是没有意义的。它不是一个对象,它是一个特殊的引用值,使变量引用";没有对象";。

如果null可以分配给任何对象类型

这就是为什么我怀疑您对对象和变量之间的区别感到困惑:您不将null分配给对象,而是分配给变量("任何对象类型"的,与"非基元类型"的"相同)。

*:我们在这里讨论的是非原始类型的变量

对于更高级的理解:

null有点坏名声(这是许多错误的原因)。您可能希望使用java.util.Optional来帮助防止null引起的某些问题。

另请参阅空对象模式,这是一种关于具有表示"空"的特殊对象的想法的设计模式;空值";。这在特殊情况下可能很有用。

Null可能被定义为唯一的Object,其行为与null引用非常相似。它可以是一个具有唯一名称的singleton,否则不可实例化;它可以与CCD_ 16相比等于自身,而与其他非CCD_;它可能有一个唯一的类,比如Null

事实上,这是一种常见的设计模式,称为空对象模式。

为什么不是这样呢?

  • Object变量可以引用任何类的对象。但反过来就不行了。您不能将Object填充到任何您喜欢的变量中。我不会写:

    String str = new Object();
    

    空对象仍然需要特殊的语言支持。如果null是类Object或类Null的单例对象,那么可以将其分配给Object变量,当然,但不能将其分配到StringArrayList变量。Java将需要不同的类型安全规则,为这个null对象创建一个例外,以便将其分配给任何类型。

  • null对象模式通常是特定于类的。您为一个特定的类创建一个null对象,然后在null对象上为该类的方法实现合理的行为。例如,您可以创建一个";空";列表,其行为类似于一个空列表,在迭代时不返回任何元素,在查询时返回大小为0

    这不适用于通用的null对象。类Object或类Null的null对象不会在任意子类上实现可用的方法。如果null是一个对象,那么如果在File引用上调用null.open("...")或在Thread上调用null.start()会发生什么?这些方法不会被定义。

    同样,必须有特殊的语言支持。也许这些电话可以自己返回null?(不过,如果他们返回void怎么办?)或者他们可以投掷NullObjectException

    在某种程度上,您只是在重新设计空引用。

  • 最后,最简单的答案是:不是那样,因为这是另一种方式。Null可以是指向任何位置的引用,也可以是对Null对象的引用。即使两者都是同样好的解决方案,也不可能两者都是。你在问为什么它是";A";而不是";B";。如果是";B";,有人会问为什么它不是";A";。

简单的答案是"因为它在语言中没有这样定义;。

从概念上讲,区别是";null是一个特殊的Object";与";null不是对象";。

考虑到对null的特殊处理,例如,null.equals("something")将抛出一个异常,这对someObject.equals(null)来说是不正确的,我认为后一种观点——null不是对象——更连贯。

可以。就像Object是所有(非基元)类型的超类型一样,Null可以是所有类型的子类型,只有一个实例null

Null将具有所有可能的方法,这些方法在被调用时都将抛出NullReferenceException,以及每个可能的字段,这些字段在被访问时也将抛出。

最终,这将与目前的情况无法区分。

最新更新