什么是Java中的null?

什么是null

什么是null的实例?

什么集合null属于?

记忆中如何performance?

什么是空的实例?

不,没有null是一个instanceoftypes。

15.20.2types比较运算符instanceof

 RelationalExpression: RelationalExpression instanceof ReferenceType 

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

这意味着对于任何typesER ,对于任何E o ,其中o == nullo 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引用值xx.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的返回值并不一定表示映射不包含该键的映射; 地图也可能明确地将密钥映射到nullcontainsKey操作可以用来区分这两种情况。

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

相比之下, java.util.Hashtable通过不允许null键和值保持简单。 它的V get(Object key) ,如果返回null ,则明确表示该键未映射。

您可以通读其余的API并找出在哪里以及如何使用null 。 请记住,他们并不总是最好的做法的例子。

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

  • 未初始化的状态
  • 终止条件
  • 不存在的对象
  • 未知的价值

记忆中如何performance?

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


null是好事吗?

这现在是主观的界限。 有些人说, null会导致许多程序员错误,可以避免。 有人说,在像Java这样的捕获NullPointerExceptionexception的语言中,使用它是很好的,因为在程序员错误上你会失败。 有些人通过使用空对象模式等来避免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设置为nullObject o = null;
  • ifnullifnonnull :例如比较一个对象为nullif (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值。