null是一个实例吗?
不,没有null
是instanceof
的类型.
instanceof
RelationalExpression: RelationalExpression instanceof ReferenceType
在运行时,如果RelationalExpression的值不是
null
,则instanceof
运算符的结果是true
,并且可以将引用强制转换为ReferenceType,而无需引发ClassCastException
.否则结果为false
.
这意味着对于任何类型E
和R
,对于任何类型E o
,其中o == null
、o instanceof R
始终是false
.
"null"属于哪个集合?
还有一种特殊的null类型,表达式
null
的类型,它没有名字.因为null类型没有名称,所以不可能声明null类型的变量或转换为null类型.null
引用是null类型表达式的唯一可能值.null
引用始终可以转换为任何引用类型.实际上,程序员可以忽略null类型,假装null
只是一个特殊的文本,可以是任何引用类型.
什么是空的?
正如上面引用的JLS所说,在实践中,你可以简单地假装它"只是一个特殊的文字,可以是任何引用类型".
在Java中,null == null
(在其他语言中并不总是如此).另请注意,根据合同,它还具有以下特殊属性(从java.lang.Object
开始):
public boolean equals(Object obj)
个对于任何非
null
的参考值x
,x.equals(null)
应为return false
.
对于所有引用类型,它也是default value(对于具有它们的变量):
- Each class variable, instance variable, or array component is initialized with a default value when it is created:
- 对于所有引用类型,默认值为
null
.
它的使用方式各不相同.您可以使用它来启用所谓的lazy initialization个字段,其中一个字段在实际使用之前其初始值为null
,并被"真实"值替换(计算成本可能很高).
还有其他用途.让我们从java.lang.System
的例子来看:
public static Console console()
Returns:系统控制台(如果有),否则为
null
.
这是一个非常常用的模式:null
用于表示对象不存在.
下面是另一个用法示例,这次是java.io.BufferedReader
:
public String readLine() throws IOException
个Returns:包含行内容的
String
,不包括任何行终止字符,或者null
,如果已经到达流的末尾.
在这里,每行readLine()
会返回instanceof String
,直到最后返回null
表示结束.这允许您按如下方式处理每一行:
String line;
while ((line = reader.readLine()) != null) {
process(line);
}
可以对API进行设计,使终止条件不依赖于readLine()
返回null
,但是可以看到这种设计的好处是使事情简明扼要.请注意,空行没有问题,因为空行"" != null
.
让我们再举一个例子,这一次是从java.util.Map<K,V>
开始:
V get(Object key)
个返回指定键映射到的值,如果此映射不包含该键的映射,则返回
null
.如果该映射允许
null
个值,那么返回值null
并不一定表示该映射不包含键的映射;也有可能映射将密钥显式映射到null
.containsKey
操作可用于区分这两种情况.
在这里,我们开始了解使用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.
你可以通读一下接口的睡觉,了解null
在哪里使用,如何使用.一定要记住,它们并不总是best practice个例子.
一般来说,null
作为一个特殊值来表示:
它在内存中是如何表示的?
在Java ?不关你的事.最好保持这样.
null
a good thing?这现在是主观的边缘.有人说null
导致了许多本可以避免的程序员错误.有人说,在一种像Java这样的语言中,使用它是很好的,因为在程序员出错时,你会很快失败.有些人用Null object pattern等来避免null
.
这本身就是一个巨大的话题,所以最好作为另一个问题的答案来讨论.
我将引用null
的发明者自己的一句话来结束这段话,C.A.R Hoare(快速排序成名):
I call it my billion-dollar mistake.这是1965年
null
号参考号的发明.当时,我正在设计第一个面向对象语言(ALGOL W)中引用的综合类型系统.我的目标是确保引用的所有使用都是绝对安全的,由编译器自动执行判断.但我忍不住想输入null
个引用,因为它很容易实现.这导致了无数错误、漏洞和系统崩溃,在过go 40年中,这些错误、漏洞和系统崩溃可能造成了10亿美元的痛苦和损失.
video of this presentation更深;这是一款推荐的手表.