什么是Java中的null?
什么是null
?
什么是null
的实例?
什么集合null
属于?
记忆中如何performance?
什么是空的实例?
不,没有null
是一个instanceof
types。
15.20.2types比较运算符instanceof
RelationalExpression: RelationalExpression instanceof ReferenceType
在运行时,如果RelationalExpression的值不为
null
并且可以将引用强制转换为ReferenceType而不引发ClassCastException
,则instanceof
运算符的结果为true
。 否则结果是false
。
这意味着对于任何typesE
和R
,对于任何E o
,其中o == null
, o instanceof R
始终为false
。
“null”属于哪一组?
JLS 4.1种类和价值的种类
还有一个特殊的空types,expression式为
null
的types,它没有名字。 因为nulltypes没有名称,所以不可能声明nulltypes的variables或转换为nulltypes。null
引用是空typesexpression式的唯一可能值。null
引用总是可以转换为任何引用types。 实际上,程序员可以忽略空types,只是假装null
只是一个特殊的文字,可以是任何引用types。
什么是空?
正如上面的JLS报价所说,在实践中,你可以简单地假装它“仅仅是一个特殊的文字,可以是任何参考types”。
在Java中, null == null
(在其他语言中并不总是这种情况)。 还要注意,通过契约,它也有这个特殊的属性(来自java.lang.Object
):
public boolean equals(Object obj)
对于任何非
null
引用值x
,x.equals(null)
应该return false
。
对于所有参考types,这也是默认值 (对于具有它们的variables):
JLS 4.12.5variables的初始值
- 创build时,每个类variables,实例variables或数组组件都会使用默认值进行初始化:
- 对于所有引用types,默认值为
null
。
这是如何使用不同。 您可以使用它来启用所谓的延迟初始化字段,其中一个字段的初始值为null
直到实际使用,它被“真实”值replace(这可能是昂贵的计算)。
还有其他用途。 我们来看一个来自java.lang.System
实例:
public static Console console()
返回 :系统控制台(如果有),否则为
null
。
这是一个非常常见的使用模式: null
用来表示对象的不存在。
这里是另一个用法示例,这次是从java.io.BufferedReader
:
public String readLine() throws IOException
返回 :包含行内容的
String
,不包括任何行终止字符;如果已到达stream尾,则返回null
。
所以在这里, readLine()
会为每一行返回instanceof String
,直到它最终返回一个null
来表示结束。 这使您可以按如下方式处理每一行:
String line; while ((line = reader.readLine()) != null) { process(line); }
可以deviseAPI以使终止条件不依赖于readLine()
返回null
,但是可以看出这个devise具有使事情简洁的好处。 请注意,空行没有问题,因为空行"" != null
。
再举一个例子,这次从java.util.Map<K,V>
:
V get(Object key)
返回指定键映射到的
null
如果此映射不包含键映射,则返回null
。如果这个映射允许
null
值,那么null
的返回值并不一定表示映射不包含该键的映射; 地图也可能明确地将密钥映射到null
。containsKey
操作可以用来区分这两种情况。
在这里,我们开始看到如何使用null
可以使事情复杂化。 第一条语句说,如果键未映射,则返回null
。 第二条语句说即使密钥被映射, 也可以返回null
。
相比之下, java.util.Hashtable
通过不允许null
键和值保持简单。 它的V get(Object key)
,如果返回null
,则明确表示该键未映射。
您可以通读其余的API并找出在哪里以及如何使用null
。 请记住,他们并不总是最好的做法的例子。
一般来说, null
用来表示一个特殊的值:
- 未初始化的状态
- 终止条件
- 不存在的对象
- 未知的价值
记忆中如何performance?
在Java中? 没关系。 最好保持这种方式。
null
是好事吗?
这现在是主观的界限。 有些人说, null
会导致许多程序员错误,可以避免。 有人说,在像Java这样的捕获NullPointerException
exception的语言中,使用它是很好的,因为在程序员错误上你会失败。 有些人通过使用空对象模式等来避免null
这是一个巨大的话题,所以最好能够回答另一个问题。
我将以null
的发明者自己的名言CAR Hoare (快速成名)的名言结束:
我把它称为我十亿美元的错误。 这是1965年
null
引用的发明。当时,我正在devise面向对象语言(ALGOL W)的第一个全面的引用types系统。 我的目标是确保所有引用的使用都是绝对安全的,编译器会自动执行检查。 但是,我忍不住引入null
引用的诱惑,仅仅因为它很容易实现。 这导致了无数的错误,漏洞和系统崩溃,在过去的四十年里可能造成了十亿美元的痛苦和损失。
这个演讲的video更深入; 这是一个推荐的手表。
什么是空的实例?
不,这就是为什么null instanceof X
将为所有类X
返回false
。 (不要被这样一个事实所迷惑,你可以把null
赋值给一个types为对象types的variables,严格地说,赋值包含一个隐式types转换;见下文)。
“null”属于哪一组?
它是nulltypes的唯一成员,其中nulltypes定义如下:
“还有一个特殊的nulltypes,expression式为null的types,它没有名字,因为nulltypes没有名字,所以不可能声明一个nulltypes的variables或者转换为nulltypes,null引用是空typesexpression式的唯一可能值,空引用总是可以转换为任何引用types,实际上,程序员可以忽略空types,只是假装null只是一个特殊的文字参考types“。 JLS 4.1
什么是空?
往上看。 在某些情况下, null
用于表示“无对象”或“未知”或“不可用”,但这些含义是应用程序特定的。
记忆中如何performance?
这是特定于实现的,在纯Java程序中,您将无法看到null
的表示forms。 (但是,如果不是所有的Java实现, null
被表示为零机器地址/指针)。
什么是空?
这没什么。
什么是空的实例?
不,因为它不是什么它不能是任何事情的实例。
什么集合null属于?
没有任何设置
记忆中如何performance?
如果有些参考指向它:
Object o=new Object();
在堆内存中分配给新创build的对象的一些空间。 o将指向内存中指定的空间。
现在o=null;
这意味着现在不会指向对象的内存空间。
不,它不是任何事情的实例,instanceof将永远是错误的。
null关键字是表示空引用的文字, 不引用任何对象 。 null是引用typesvariables的默认值。
也可以看看
null:Java术语表
Java中的空(tm)
在C和C ++中,“NULL”是一个在头文件中定义的常量,其值如下:
0
要么:
0L
要么:
((void*)0)
取决于编译器和内存模型选项。 严格地说,NULL不是C / C ++本身的一部分。
在Java(tm)中,“null”不是关键字,而是nulltypes的特殊文字。 它可以转换为任何引用types,但不能转换为任何基本types,如int或boolean。 null文字不一定具有零值。 并且不可能转换为nulltypes或声明这种types的variables。
空不是任何类的实例。
但是,您可以将null分配给任何(对象或数组)types的variables:
// this is false boolean nope = (null instanceof String); // but you can still use it as a String String x = null; "abc".startsWith(null);
null
是特殊值,它不是任何事物的实例。 由于显而易见的原因,它不能是任何事物的instanceof
。
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
具有直接的JVM支持:使用三条指令来实现它:
-
aconst_null
:例如将一个variables设置为null
如Object o = null;
-
ifnull
和ifnonnull
:例如比较一个对象为null
如if (o == null)
第6章“Java虚拟机指令集”提到了null
对其他指令的影响:它为其中的许多指令抛出了NullPointerException
。
2.4。 “引用types和值”在generics中也提到了null
:
一个引用值也可以是特殊的空引用,对没有对象的引用,这里用null表示。 空引用最初没有运行时types,但可以转换为任何types。 引用types的默认值为null。
在我看来,在Java中看到null的一个有趣的方式是将它看作是不表示缺less信息,而仅仅是作为可以被分配给任何types的引用的文字值。 如果你仔细想想,如果它表示没有信息,那么对于a1 == a2来说,这是真的没有意义(如果它们都被赋值为null),因为它们实际上可能指向ANY对象(我们只是不知道他们应该指向什么对象)…顺便说一句null == null在Java中返回true。 如果java例如将像SQL:1999那么null == null将返回未知(SQL:1999中的布尔值可以采取三个值:true,false和未知,但在实践中,未知在实际系统中实现为null)… http://en.wikipedia.org/wiki/SQL
在Java中有两种主要的types: 基元和引用 。 原始types声明的variables存储值; 声明引用types存储引用的variables。
String x = null;
在这种情况下,初始化语句声明一个variables“x”。 “x”存储string引用。 这里是空的 。 首先,null不是一个有效的对象实例,所以没有为它分配内存。 它只是一个值,表示对象引用当前不引用对象。
从JLS正式回答所有问题的简短而精确的答案:
3.10.7。 空字面
空types有一个值,即空字符,由空字符空值表示,由ASCII字符组成。
null文字总是空types。
只分配了分配给null的types的引用。 您不要将任何值(对象)分配给引用。 这样的分配是JVM特有的,需要多less引用以及将在哪个内存区域分配。
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是什么? 如果没有,那么我build议你在C / C ++中学习指针,然后你就会明白了。
请注意,在C中,与C ++不同,nullptr是未定义的,但使用了NULL,也可以在C ++中使用,但在C ++中,nullptr比NULL更为可取,因为C中的NULL始终与指针相关,所以在C ++中后缀“ptr”被追加到单词的结尾,并且所有的字母现在都是小写,但是这不重要。
在Java中,每个非基元types的variables总是引用该types的对象或inheritance,而null则为空类对象引用,但不是空指针,因为在Java中没有这样的事物“指针”,而是引用类对象被用来代替,而Java中的null与类对象引用有关,所以你也可以把它叫做“nullref”或者“nullrefobj”,但是这个很长,所以把它叫做“null”。
在C ++中,你可以使用指针和可选成员/variables的nullptr值,即没有值的成员/variables,如果没有值,那么它等于nullptr,所以可以使用Java中的null值。