Java 中的 null 是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2707322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is null in Java?
提问by unj2
What is null
?
什么是null
?
Is null
an instance of anything?
是null
任何东西的实例吗?
What set does null
belong to?
null
属于什么集合?
How is it represented in the memory?
它在内存中是如何表示的?
采纳答案by polygenelubricants
Is null an instance of anything?
null 是任何东西的实例吗?
No, there is no type which null
is an instanceof
.
不,没有类型null
是instanceof
.
15.20.2 Type Comparison Operator instanceof
15.20.2 类型比较运算符 instanceof
RelationalExpression: RelationalExpression instanceof ReferenceType
At run time, the result of the
instanceof
operator istrue
if the value of the RelationalExpressionis notnull
and the reference could be cast to the ReferenceTypewithout raising aClassCastException
. Otherwise the result isfalse
.
RelationalExpression: RelationalExpression instanceof ReferenceType
在运行时,
instanceof
运算符的结果是RelationalExpressiontrue
的值是否不是,并且可以将引用强制转换为ReferenceType而不引发. 否则结果是。null
ClassCastException
false
This means that for any type E
and R
, for any E o
, where o == null
, o instanceof R
is always false
.
这意味着对于任何类型的E
和R
,对于任何E o
,在那里o == null
,o instanceof R
永远是false
。
What set does 'null' belong to?
'null' 属于哪个集合?
JLS 4.1 The Kinds of Types and Values
JLS 4.1 类型和值的种类
There is also a special nulltype, the type of the expression
null
, which has no name. Because the nulltype has no name, it is impossible to declare a variable of the nulltype or to cast to the nulltype. Thenull
reference is the only possible value of an expression of nulltype. Thenull
reference can always be cast to any reference type. In practice, the programmer can ignore the nulltype and just pretend thatnull
is merely a special literal that can be of any reference type.
还有一种特殊的空类型,表达式的类型
null
,它没有名字。因为null类型没有名字,所以无法声明null类型的变量或强制转换为null类型。所述null
参考是一个表达式的唯一可能的值无效的类型。该null
参考总是可以被转换为任何引用类型。在实践中,程序员可以忽略null类型并假装它null
只是一个可以是任何引用类型的特殊文字。
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".
正如上面的 JLS 引用所说,在实践中,您可以简单地假设它“只是一个可以是任何引用类型的特殊文字”。
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
):
在 Java 中null == null
(在其他语言中并非总是如此)。另请注意,根据合同,它还具有以下特殊属性(来自java.lang.Object
):
public boolean equals(Object obj)
For any non-
null
reference valuex
,x.equals(null)
shouldreturn false
.
public boolean equals(Object obj)
对于任何非
null
参考值x
,x.equals(null)
应该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
JLS 4.12.5 变量的初始值
- Each class variable, instance variable, or array component is initialized with a default valuewhen it is created:
- For all reference types, the default value is
null
.
- 每个类变量、实例变量或数组组件在创建时都使用默认值进行初始化:
- 对于所有引用类型,默认值为
null
。
How this is used varies. You can use it to enable what is called lazy initializationof 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).
它的使用方式各不相同。您可以使用它来启用所谓的字段延迟初始化,其中一个字段null
在实际使用之前将具有其初始值
There are also other uses. Let's take a real example from java.lang.System
:
还有其他用途。让我们举一个真实的例子java.lang.System
:
public static Console console()
Returns: The system console, if any, otherwise
null
.
public static Console console()
返回: 系统控制台(如果有),否则返回
null
。
This is a very common use pattern: null
is used to denote non-existence of an object.
这是一个非常常见的使用模式:null
用于表示对象不存在。
Here's another usage example, this time from java.io.BufferedReader
:
这是另一个使用示例,这次来自java.io.BufferedReader
:
public String readLine() throws IOException
Returns: A
String
containing the contents of the line, not including any line-termination characters, ornull
if the end of the stream has been reached.
public String readLine() throws IOException
返回: A
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:
所以在这里,readLine()
会instanceof String
为每一行都返回,直到它最终返回一个null
来表示结束。这允许您按如下方式处理每一行:
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
.
可以设计 API 使终止条件不依赖于readLine()
返回null
,但可以看到这种设计具有使事情简洁的好处。请注意,空行没有问题,因为空行"" != null
。
Let's take another example, this time from java.util.Map<K,V>
:
让我们再举一个例子,这次来自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 ofnull
does not necessarily indicate that the map contains no mapping for the key; it's also possible that the map explicitly maps the key tonull
. ThecontainsKey
operation may be used to distinguish these two cases.
V get(Object key)
返回指定键映射到的值,或者
null
如果此映射不包含键的映射。如果此映射允许
null
值,则返回值null
不一定表示该映射不包含该键的映射;地图也有可能将键显式映射到null
. 该containsKey
操作可用于区分这两种情况。
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 alsobe returned.
在这里,我们开始看到使用null
如何使事情复杂化。第一条语句表示如果键未映射,null
则返回。第二个声明说,即使按键映射,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.
相反,java.util.Hashtable
通过不允许null
键和值使事情更简单;它的V get(Object key)
,如果返回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 practiceexamples.
您可以通读其余的 API 并找到使用的位置和方式null
。请记住,它们并不总是最佳实践示例。
Generally speaking, null
are used as a special value to signify:
一般来说,null
用作特殊值来表示:
- 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?
是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.
这现在是临界主观的。有人说这null
会导致许多本可以避免的程序员错误。有人说,在NullPointerException
像 Java 这样的语言中,最好使用它,因为您将在程序员错误时快速失败。有些人null
通过使用Null object pattern等来避免。
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):
我将引用null
他自己的发明者CAR Hoare(以快速排序而闻名)的一句话结束:
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 anull
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.
我称之为我的十亿美元错误。它是
null
1965 年引用的发明。当时,我正在为面向对象语言 (ALGOL W) 中的引用设计第一个综合类型系统。我的目标是确保所有引用的使用都绝对安全,并由编译器自动执行检查。但我无法抗拒null
引用的诱惑,仅仅因为它很容易实现。这导致了无数错误、漏洞和系统崩溃,在过去的四十年里,这些问题可能造成了 10 亿美元的痛苦和损失。
The video of this presentationgoes deeper; it's a recommended watch.
回答by Adriaan Stander
The null keyword is a literal that represents a null reference, one that does not refer to any object. null is the default value of reference-type variables.
null 关键字是表示空引用的文字,不引用任何对象。null 是引用类型变量的默认值。
Also maybe have a look at
也可以看看
回答by Tom
No it's not the instance of anything, instanceof will always be false.
不,它不是任何东西的实例,instanceof 总是假的。
回答by Itay Maman
null
is a special value that is not an instance of any class. This is illustrated by the following program:
null
是一个特殊值,它不是任何类的实例。以下程序说明了这一点:
public class X {
void f(Object o)
{
System.out.println(o instanceof String); // Output is "false"
}
public static void main(String[] args) {
new X().f(null);
}
}
回答by Stephen C
Is null an instance of anything?
null 是任何东西的实例吗?
No. That is why null instanceof X
will return false
for all classes X
. (Don't be fooled by the fact that you can assign null
to a variable whose type is an object type. Strictly speaking, the assignment involves an implicit type conversion; see below.)
不。这就是为什么null instanceof X
会返回false
所有类X
。(不要被您可以分配null
给类型为对象类型的变量这一事实所迷惑。严格来说,分配涉及隐式类型转换;见下文。)
What set does 'null' belong to?
'null' 属于哪个集合?
It is the one and only member of the null type, where the null type is defined as follows:
它是 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."JLS 4.1
“还有一种特殊的空类型,表达式null的类型,它没有名字。因为空类型没有名字,所以不能声明空类型的变量或强制转换为空类型。空引用是空类型表达式的唯一可能值。空引用始终可以转换为任何引用类型。在实践中,程序员可以忽略空类型并假装空只是一个特殊的文字,可以是任何引用类型。” JLS 4.1
What is null?
什么是空?
See above. In some contexts, null
is used to denote "no object" or "unknown" or "unavailable", but these meanings are application specific.
看上面。在某些上下文中,null
用于表示“无对象”或“未知”或“不可用”,但这些含义是特定于应用程序的。
How is it represented in the memory?
它在内存中是如何表示的?
That is implementation specific, and you won't be able to see the representation of null
in a pure Java program. (But null
is represented as a zero machine address / pointer in most if not all Java implementations.)
这是特定于实现的,您将无法null
在纯 Java 程序中看到 的表示。(但null
在大多数(如果不是所有)Java 实现中都表示为零机器地址/指针。)
回答by fastcodejava
null
is special value, it is not instance of anything. For obviously reason it cannot be instanceof
anything.
null
是特殊值,它不是任何东西的实例。出于明显的原因,它不可能是instanceof
任何东西。
回答by Thilo
Null is not an instance of any class.
Null 不是任何类的实例。
However, you can assign null to variables of any (object or array) type:
但是,您可以将 null 分配给任何(对象或数组)类型的变量:
// this is false
boolean nope = (null instanceof String);
// but you can still use it as a String
String x = null;
"abc".startsWith(null);
回答by p27
Null in Java(tm)
Java中的空(tm)
In C and C++, "NULL" is a constant defined in a header file, with a value like:
在 C 和 C++ 中,“NULL”是在头文件中定义的常量,其值类似于:
0
or:
或者:
0L
or:
或者:
((void*)0)
depending on the compiler and memory model options. NULL is not, strictly speaking, part of C/C++ itself.
取决于编译器和内存模型选项。严格来说,NULL 不是 C/C++ 本身的一部分。
In Java(tm), "null" is not a keyword, but a special literal of the null type. It can be cast to any reference type, but not to any primitive type such as int or boolean. The null literal doesn't necessarily have value zero. And it is impossible to cast to the null type or declare a variable of this type.
在 Java(tm) 中,“null”不是关键字,而是 null 类型的特殊文字。它可以转换为任何引用类型,但不能转换为任何原始类型,例如 int 或 boolean。空文字不一定具有零值。并且不可能强制转换为空类型或声明这种类型的变量。
回答by Sanjay Jain
What is null?
什么是空?
It is nothing.
没什么。
Is null an instance of anything?
null 是任何东西的实例吗?
No as it is nothing It can't be instance of any thing.
不,因为它什么都不是它不能是任何事物的实例。
What set does null belong to?
null 属于哪个集合?
No any set
没有任何设置
How is it represented in the memory?
它在内存中是如何表示的?
If some reference points to it like:
如果某些参考指向它,例如:
Object o=new Object();
In heap memory some space assigned to new created object. And o will point to that assigned space in memory.
在堆内存中分配给新创建的对象的一些空间。o 将指向内存中分配的空间。
Now o=null;
现在 o=null;
This means now o will not point to that memory space of object.
这意味着现在 o 不会指向对象的那个内存空间。
回答by Bat0u89
An interesting way to see null in java in my opinion is to see it as something that DOES NOT denote an absence of information but simply as a literal value that can be assigned to a reference of any type. If you think about it if it denoted absence of information then for a1==a2 to be true doesn't make sense (in case they were both assigned a value of null) as they could really could be pointing to ANY object (we simply don't know what objects they should be pointing to)... By the way null == null returns true in java. If java e.g. would be like SQL:1999 then null==null would return unknown (a boolean value in SQL:1999 can take three values : true,false and unknown but in practise unknown is implemented as null in real systems)... http://en.wikipedia.org/wiki/SQL
在我看来,在 java 中查看 null 的一种有趣方式是将其视为不表示缺少信息而只是作为可以分配给任何类型引用的文字值的东西。如果你考虑一下,如果它表示没有信息,那么 a1==a2 为真是没有意义的(如果它们都被分配了一个 null 值),因为它们真的可以指向任何对象(我们只是不知道他们应该指向什么对象)......顺便说一下,null == null 在java中返回true。如果java eg 会像SQL:1999 那么null==null 将返回unknown(SQL:1999 中的布尔值可以取三个值:true、false 和unknown,但实际上unknown 在实际系统中被实现为null)... http://en.wikipedia.org/wiki/SQL