Java 中的 null 是什么? [英] What is null in Java?

查看:24
本文介绍了Java 中的 null 是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是null?

null 是任何东西的实例吗?

null 属于哪个集合?

它在内存中是如何表示的?

解决方案

null 是任何东西的实例吗?

不,不存在 nullinstanceof 的类型.

15.20.2 类型比较运算符 instanceof

<块引用>

关系表达式:RelationalExpression 实例的 ReferenceType

在运行时,如果RelationalExpression 的值不是null,instanceof 运算符的结果是truecode> 并且引用可以转换为 ReferenceType 而不会引发 ClassCastException.否则结果为 false.

这意味着对于任何类型ER,对于任何E o,其中o == null>, o instanceof R 总是 false.

<小时><块引用>

'null'属于哪个集合?

JLS 4.1 类型的种类和价值观

<块引用>

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

<小时><块引用>

什么是空?

正如上面的 JLS 引用所说,在实践中,您可以简单地假设它只是一个可以是任何引用类型的特殊文字".

在 Java 中,null == null(在其他语言中并非总是如此).另请注意,根据合同,它还具有此特殊属性(来自 java.lang.Object):

<块引用>

public boolean equals(Object obj)

对于任何非<​​code>null引用值xx.equals(null)应该return false.

它也是所有引用类型的默认值(对于具有它们的变量):

JLS 4.12.5变量的初始值

<块引用>
  • 每个类变量、实例变量或数组组件在创建时都使用默认值进行初始化:
    • 对于所有引用类型,默认值为 null.

它的使用方式各不相同.您可以使用它来启用所谓的字段延迟初始化,其中一个字段的初始值将是 null 直到它被实际使用,在那里它被真实的" 值(计算起来可能很昂贵).

还有其他用途.让我们从 <举一个真实的例子代码>java.lang.System:

<块引用>

public static Console console()

返回:系统控制台,如果有,否则null.

这是一个非常常见的使用模式:null 用于表示对象不存在.

这是另一个用法示例,这次来自 java.io.BufferedReader:

<块引用>

public String readLine() 抛出 IOException

返回:包含行内容的String,不包括任何行终止符,或者null,如果行的结尾已到达流.

所以在这里,readLine() 将为每一行返回 instanceof String,直到它最终返回一个 null 来表示结束.这允许您按如下方式处理每一行:

字符串行;while ((line = reader.readLine()) != null) {流程(线);}

可以设计 API 使终止条件不依赖于 readLine() 返回 null,但是可以看到这种设计的好处是东西简洁.注意空行没有问题,因为空行"" != null.

再举一个例子,这次来自 java.util.Map:

<块引用>

V get(Object key)

返回指定键映射到的值,如果此映射不包含键的映射,则返回 null.

如果此映射允许 null 值,则返回值 null 并不一定表示该映射不包含该键的映射;也有可能映射显式地将键映射到 null.containsKey 操作可用于区分这两种情况.

在这里,我们开始看到使用 null 如何使事情复杂化.第一条语句表示,如果键未映射,则返回 null.第二个语句表示即使键被映射,null 也可以返回.

相比之下,java.util.Hashtable 通过不允许 null 键和值使事情变得更简单;它的V get(Object key),如果返回null,明确表示key没有映射.

您可以通读其余的 API 并了解 null 的使用位置和使用方式.请记住,它们并不总是最佳实践示例.

一般来说,null作为一个特殊的值来表示:

  • 未初始化状态
  • 终止条件
  • 不存在的对象
  • 未知值
<小时><块引用>

它在内存中是如何表示的?

在 Java 中?不关你事.最好保持这种状态.

<小时>

null 是好事吗?

这现在是主观的边缘.有人说 null 会导致许多本可以避免的程序员错误.有人说,在像 Java 这样捕获 NullPointerException 的语言中,最好使用它,因为您将在程序员错误时快速失败.有些人通过使用空对象模式等来避免null.>

这本身就是一个巨大的话题,因此最好将其作为另一个问题的答案进行讨论.

我将引用 null 的发明者本人的话作为结尾,CAR Hoare(快速排序成名):

<块引用>

我称之为我的十亿美元错误.这是 1965 年 null 引用的发明.当时,我正在设计第一个综合类型系统面向对象语言 (ALGOL W) 中的引用.我的目标是确保所有引用的使用都绝对安全,并由编译器自动执行检查.但是我无法抗拒放入 null 引用的诱惑,仅仅因为它很容易实现.这导致了无数错误、漏洞和系统崩溃,在过去的四十年里,这些问题可能造成了 10 亿美元的痛苦和损失.

本次演示视频 更深入;值得推荐的手表.

What is null?

Is null an instance of anything?

What set does null belong to?

How is it represented in the memory?

解决方案

Is null an instance of anything?

No, there is no type which null is an instanceof.

15.20.2 Type Comparison Operator instanceof

RelationalExpression:
    RelationalExpression instanceof ReferenceType

At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast to the ReferenceType without raising a ClassCastException. Otherwise the result is false.

This means that for any type E and R, for any E o, where o == null, o instanceof R is always false.


What set does 'null' belong to?

JLS 4.1 The Kinds of Types and Values

There is also a special null type, the type of the expression null, which has no name. Because the null type has no name, it is impossible to declare a variable of the null type or to cast to the null type. The null reference is the only possible value of an expression of null type. The null reference can always be cast to any reference type. In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type.


What is null?

As the JLS quote above says, in practice you can simply pretend that it's "merely a special literal that can be of any reference type".

In Java, null == null (this isn't always the case in other languages). Note also that by contract, it also has this special property (from java.lang.Object):

public boolean equals(Object obj)

For any non-null reference value x, x.equals(null) should return false.

It is also the default value (for variables that have them) for all reference types:

JLS 4.12.5 Initial Values of Variables

  • Each class variable, instance variable, or array component is initialized with a default value when it is created:
    • For all reference types, the default value is null.

How this is used varies. You can use it to enable what is called lazy initialization of fields, where a field would have its initial value of null until it's actually used, where it's replaced by the "real" value (which may be expensive to compute).

There are also other uses. Let's take a real example from java.lang.System:

public static Console console()

Returns: The system console, if any, otherwise null.

This is a very common use pattern: null is used to denote non-existence of an object.

Here's another usage example, this time from java.io.BufferedReader:

public String readLine() throws IOException

Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached.

So here, readLine() would return instanceof String for each line, until it finally returns a null to signify the end. This allows you to process each line as follows:

String line;
while ((line = reader.readLine()) != null) {
   process(line);
}

One can design the API so that the termination condition doesn't depend on readLine() returning null, but one can see that this design has the benefit of making things concise. Note that there is no problem with empty lines, because an empty line "" != null.

Let's take another example, this time from java.util.Map<K,V>:

V get(Object key)

Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.

If this map permits null values, then a return value of null does not necessarily indicate that the map contains no mapping for the key; it's also possible that the map explicitly maps the key to null. The containsKey operation may be used to distinguish these two cases.

Here we start to see how using null can complicate things. The first statement says that if the key isn't mapped, null is returned. The second statement says that even if the key is mapped, null can also be returned.

In contrast, java.util.Hashtable keeps things simpler by not permitting null keys and values; its V get(Object key), if returns null, unambiguously means that the key isn't mapped.

You can read through the rest of the APIs and find where and how null is used. Do keep in mind that they aren't always the best practice examples.

Generally speaking, null are used as a special value to signify:

  • Uninitialized state
  • Termination condition
  • Non-existing object
  • An unknown value

How is it represented in the memory?

In Java? None of your concern. And it's best kept that way.


Is null a good thing?

This is now borderline subjective. Some people say that null causes many programmer errors that could've been avoided. Some say that in a language that catches NullPointerException like Java, it's good to use it because you will fail-fast on programmer errors. Some people avoid null by using Null object pattern, etc.

This is a huge topic on its own, so it's best discussed as answer to another question.

I will end this with a quote from the inventor of null himself, C.A.R Hoare (of quicksort fame):

I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.

The video of this presentation goes deeper; it's a recommended watch.

这篇关于Java 中的 null 是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆