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

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

问题描述

什么是 null

null 是什么实例?

null 属于哪个集合?

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

How is it represented in the memory?

推荐答案


null是否为任何实例?

Is null an instance of anything?

不,没有类型 null instanceof


RelationalExpression:
    RelationalExpression instanceof ReferenceType

在运行时, instanceof 运算符的结果是 true 如果 RelationalExpression 的值不是 null ,则可以将引用转换为 ReferenceType ,而不会引发 ClassCastException异常。否则结果是 false

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.

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

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


'null'属于哪个集合?

What set does 'null' belong to?



JLS 4.1类型和价值的种类



JLS 4.1 The Kinds of Types and Values


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

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.








什么是null?

What is null?

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

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".

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

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)

对于任何非<​​code> null 参考值 x x.equals(null)应该 return false

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:



  • 每个类变量,创建实例变量或数组组件时使用默认值进行初始化:


    • 对于所有引用类型,默认值value是 null

  • 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.

如何使用它会有所不同。您可以使用它来启用所谓的 lazy initialization 字段,其中字段的初始值为 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).

还有其他用途。让我们从 <中获取一个真实的例子。 code> java.lang.System

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


public static Console console()

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

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

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

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

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

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


public String readLine()throws IOException

返回:包含行内容的字符串,不包括任何行终止字符,或 null 如果strea结束已经达到了。

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.

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

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);
}

可以设计API,以便终止条件不依赖于 readLine()返回 null ,但可以看出这种设计有利于简化操作。请注意,空行没有问题,因为空行!= null

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.

我们来看看另一个例子,这次是从 java.util.Map< K,V>

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


V get(对象键)

返回指定键映射到的值,或 null 如果此地图不包含该键的映射。

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

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

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.

这里我们开始看看使用 null 如何使事情复杂化。第一个语句说如果未映射键,则返回 null 。第二个语句说,即使映射了键, null 也可以返回

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.

相比之下, java .util.Hashtable 不允许 null 键和值,使事情更简单;它的 V get(对象键),如果返回 null ,则明确表示该键未映射。

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.

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

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.

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

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?

在Java?你没关系。最好保持这种方式。

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

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

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.

我将以 null 本身的发明人引用此结尾, CAR Hoare (快速成名):

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


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

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天全站免登陆