提问人:unj2 提问时间:4/25/2010 最后编辑:Joachim Sauerunj2 更新时间:3/9/2018 访问量:388374
Java 中的 null 是什么?
What is null in Java?
答:
null 关键字是表示 null 引用的文本,该引用不引用任何对象。null 是引用类型变量的默认值。
也可以看看
评论
不,它不是任何东西的实例,instanceof 将永远是假的。
null 是任何事物的实例吗?
不,没有类型是 .null
instanceof
15.20.2 类型比较运算符 instanceof
RelationalExpression: RelationalExpression instanceof ReferenceType
在运行时,运算符的结果是,如果 RelationalExpression 的值不是,则可以将引用强制转换为 ReferenceType,而不会引发 .否则,结果是 。
instanceof
true
null
ClassCastException
false
这意味着对于任何类型和 ,对于任何 ,其中 总是 。E
R
E o
o == null
o instanceof R
false
'null' 属于什么集合?
JLS 4.1 类型和值的种类
还有一个特殊的 null 类型,即表达式的类型,它没有名称。由于 null 类型没有名称,因此无法声明 null 类型的变量或强制转换为 null 类型。引用是 null 类型的表达式的唯一可能值。引用始终可以强制转换为任何引用类型。在实践中,程序员可以忽略 null 类型,而只是假装它只是一个特殊的文字,可以是任何引用类型。
null
null
null
null
什么是空?
正如上面引用的 JLS 所说,在实践中,您可以简单地假装它“只是一个特殊的文字,可以是任何引用类型”。
在 Java 中,(在其他语言中并不总是如此)。另请注意,根据合同,它还具有以下特殊属性(来自 java.lang.Object
):null == null
public boolean equals(Object obj)
对于任何非参考值,应 .
null
x
x.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() throws IOException
返回值:包含行内容的 A,不包含任何行终止字符,或者是否已到达流的末尾。
String
null
所以在这里,将返回每一行,直到它最终返回 a 表示结束。这允许您按如下方式处理每行: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
相比之下,java.util.Hashtable
通过不允许键和值来简化事情;它的 , if 返回 ,明确表示键未映射。null
V get(Object key)
null
您可以通读其余的 API,并了解使用的位置和方式。请记住,它们并不总是最佳实践示例。null
一般来说,用作特殊值来表示:null
- 未初始化状态
- 终止条件
- 不存在的对象
- 未知值
它在内存中是如何表示的?
在 Java 中?不用担心。最好保持这种状态。
是一件好事吗?null
这现在是主观的。有人说这会导致许多本来可以避免的程序员错误。有人说,在像 Java 这样的流行语言中,使用它是件好事,因为程序员的错误会很快失败。有些人通过使用 Null 对象模式等来避免。null
NullPointerException
null
这本身就是一个巨大的话题,所以最好把它作为另一个问题的答案来讨论。
最后,我将引用他自己的发明者 C.A.R Hoare(以 quicksort 成名)的话来结束这篇文章:null
我称之为我十亿美元的错误。它是 1965 年参考的发明。当时,我正在设计第一个面向对象语言(ALGOL W)的综合类型系统。我的目标是确保所有引用的使用都应该是绝对安全的,并由编译器自动执行检查。但我无法抗拒输入参考的诱惑,仅仅因为它很容易实现。这导致了无数的错误、漏洞和系统崩溃,在过去四十年中可能造成了十亿美元的痛苦和损害。
null
null
本次演示的视频更深入;这是一款值得推荐的手表。
评论
NIL
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);
}
}
评论
null
String
void f(String o)
null 是任何事物的实例吗?
不。这就是为什么所有班级都会回来的原因.(不要被可以赋值给类型为对象类型的变量这一事实所迷惑。严格来说,赋值涉及隐式类型转换;见下文。null instanceof X
false
X
null
'null' 属于什么集合?
它是 null 类型的唯一成员,其中 null 类型定义如下:
“还有一种特殊的 null 类型,即表达式 null 的类型,它没有名称。由于 null 类型没有名称,因此无法声明 null 类型的变量或强制转换为 null 类型。null 引用是 null 类型的表达式的唯一可能值。空引用始终可以强制转换为任何引用类型。在实践中,程序员可以忽略 null 类型,而只是假装 null 只是一个特殊的文字,可以是任何引用类型。 JLS 4.1
什么是空?
见上文。在某些上下文中,用于表示“无对象”或“未知”或“不可用”,但这些含义是特定于应用程序的。null
它在内存中是如何表示的?
这是特定于实现的,您将无法在纯 Java 程序中看到 的表示形式。(但在大多数(如果不是全部)Java 实现中表示为零机器地址/指针。null
null
null
是特殊值,它不是任何东西的实例。出于显而易见的原因,它不可能是什么。instanceof
Null 不是任何类的实例。
但是,您可以将 null 分配给任何(对象或数组)类型的变量:
// this is false
boolean nope = (null instanceof String);
// but you can still use it as a String
String x = null;
"abc".startsWith(null);
Java(tm) 中的 Null
在 C 和 C++ 中,“NULL”是在头文件中定义的常量,其值如下:
0
艺术
0L
艺术
((void*)0)
取决于编译器和内存模型选项。严格来说,NULL 不是 C/C++ 本身的一部分。
在 Java(tm) 中,“null”不是关键字,而是 null 类型的特殊文字。它可以强制转换为任何引用类型,但不能强制转换为任何基元类型,例如 int 或 boolean。null 文本的值不一定为零。并且不可能转换为 null 类型或声明此类型的变量。
什么是空?
这没什么。
null 是任何事物的实例吗?
不,因为它什么都不是,它不能是任何事物的实例。
null 属于什么集合?
没有任何设置
它在内存中是如何表示的?
如果一些参考资料指向它,例如:
Object o=new Object();
在堆内存中,为新创建的对象分配了一些空间。o 将指向内存中分配的空间。
现在o=null;
这意味着现在 o 不会指向对象的内存空间。
评论
在我看来,在 java 中看到 null 的一种有趣方法是将其视为不表示缺少信息的东西,而只是将其视为可以分配给任何类型的引用的文字值。如果你考虑一下,如果它表示没有信息,那么 a1==a2 为 true 是没有意义的(如果它们都被分配了 null 值),因为它们真的可以指向任何对象(我们根本不知道他们应该指向什么对象)......顺便说一句,null == null 在 java 中返回 true。如果 java 例如像 SQL:1999 一样,那么 null==null 将返回 unknown(SQL:1999 中的布尔值可以采用三个值:true、false 和 unknown,但实际上 unknown 在实际系统中被实现为 null)......http://en.wikipedia.org/wiki/SQL
字节码表示
Java 具有直接的 JVM 支持:使用三条指令来实现它:null
aconst_null
:例如,将变量设置为null
Object o = null;
ifnull
和 : 例如,将对象与ifnonnull
null
if (o == null)
第 6 章“Java 虚拟机指令集”然后提到了对其他指令的影响:它为其中许多指令抛出了一个。null
NullPointerException
2.4. “引用类型和值”也以通用术语提及:null
引用值也可以是特殊的 null 引用,即对无对象的引用,此处用 null 表示。null 引用最初没有运行时类型,但可以强制转换为任何类型。引用类型的默认值为 null。
Java 中有两大类类型:原始类型和引用类型。基元类型的声明变量存储值;声明为引用类型的变量存储引用。
String x = null;
在本例中,初始化语句声明变量“x”。“x” 存储字符串引用。此处为 null。首先,null 不是一个有效的对象实例,因此没有为它分配内存。它只是一个值,指示对象引用当前未引用对象。
简短而准确的答案,正式回答了JLS的所有问题:
3.10.7. Null 文字
null 类型有一个值,即 null 引用,由 null 文字 null,由 ASCII 字符组成。
null 文本始终为 null 类型。
仅分配分配给 null 的类型的引用。您不为引用赋值任何值(对象)。 这种分配特定于 JVM,将占用多少引用以及它将在哪个内存区域中分配。
Java 中的 null 类似于/类似于 C++ 中的 nullptr。
C++ 程序:
class Point
{
private:
int x;
int y;
public:
Point(int ix, int iy)
{
x = ix;
y = iy;
}
void print() { std::cout << '(' << x << ',' << y << ')'; }
};
int main()
{
Point* p = new Point(3,5);
if (p != nullptr)
{
p->print();
p = nullptr;
}
else
{
std::cout << "p is null" << std::endl;
}
return 0;
}
Java 中的相同程序:
public class Point {
private int x;
private int y;
public Point(int ix, int iy) {
x = ix;
y = iy;
}
public void print() { System.out.print("(" + x + "," + y + ")"); }
}
class Program
{
public static void main(String[] args) {
Point p = new Point(3,5);
if (p != null)
{
p.print();
p = null;
}
else
{
System.out.println("p is null");
}
}
}
现在你从上面的代码中了解 Java 中的 null 是什么了吗?如果没有,那么我建议你学习 C/C++ 中的指针,然后你就会明白。
请注意,在 C 中,与 C++ 不同,nullptr 是未定义的,但使用 NULL,这也可以在 C++ 中使用,但在 C++ 中 nullptr 比 NULL 更可取,因为 C 中的 NULL 始终与指针相关,仅此而已,因此在 C++ 中后缀“ptr”附加到单词的末尾, 而且所有字母现在都是小写的,但这不太重要。
在 Java 中,类非原始类型的每个变量总是引用该类型的对象或继承的,而 null 是 null 类对象引用,但不是 null 指针,因为在 Java 中没有“指针”这样的东西,而是使用对类对象的引用,而 Java 中的 null 与类对象引用相关, 所以你也可以称它为“nullref”或“nullrefobj”,但这很长,所以就叫它“null”吧。
在 C++ 中,您可以将指针和 nullptr 值用于可选成员/变量,即没有值的成员/变量,如果它没有值,则它等于 nullptr,因此例如如何使用 Java 中的 null。
评论