Java 中什么是 null?

发布于 2024-08-30 04:06:12 字数 122 浏览 2 评论 0原文

什么是null

null 是任何东西的实例吗?

null 属于什么集合?

它在内存中是如何表示的?

What is null?

Is null an instance of anything?

What set does null belong to?

How is it represented in the memory?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

丢了幸福的猪 2024-09-06 04:06:13

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);

Null is not an instance of any class.

However, you can assign null to variables of any (object or array) type:

 // this is false   
 boolean nope = (null instanceof String);

 // but you can still use it as a String
 String x = null;
 "abc".startsWith(null);
舟遥客 2024-09-06 04:06:13

字节码表示

Java的null有直接的JVM支持:使用三个指令来实现它:

  • aconst_null:例如将变量设置为nullObject o = null;
  • ifnullifnonnull:例如将对象与 null 进行比较如 if (o == null)

第 6 章“Java 虚拟机指令集” 然后提到了 null 对其他指令的影响:它对其中许多指令抛出 NullPointerException

2.4。 “引用类型和值” 还以通用术语提到了 null

引用值也可以是特殊的空引用,即对无对象的引用,这里用 null 表示。空引用最初没有运行时类型,但可以转换为任何类型。引用类型的默认值为 null。

Bytecode representation

Java's null has direct JVM support: three instructions are used to implement it:

  • aconst_null: e.g. to set a variable to null as in Object o = null;
  • ifnull and ifnonnull: e.g. to compare an object to null as in if (o == null)

Chapter 6 "The Java Virtual Machine Instruction Set " then mentions the effects of null on other instructions: it throws a NullPointerException for many of them.

2.4. "Reference Types and Values" also mentions null in generic terms:

A reference value may also be the special null reference, a reference to no object, which will be denoted here by null. The null reference initially has no run-time type, but may be cast to any type. The default value of a reference type is null.

温暖的光 2024-09-06 04:06:13

null 是特殊值,它不是任何东西的实例。出于明显的原因,它不能是任何东西的实例。

null is special value, it is not instance of anything. For obviously reason it cannot be instanceof anything.

佞臣 2024-09-06 04:06:13

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 is a special value that is not an instance of any class. This is illustrated by the following program:

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);
   }
}
马蹄踏│碎落叶 2024-09-06 04:06:13

Java 中有两大类类型:原始引用。声明为基本类型的变量存储值;声明为引用类型的变量存储引用。

String x = null;

在这种情况下,初始化语句声明一个变量“x”。 “x”存储字符串引用。这里是null。首先,null不是一个有效的对象实例,因此没有为其分配内存。它只是一个值,指示对象引用当前未引用对象。

There are two major categories of types in Java: primitive and reference. Variables declared of a primitive type store values; variables declared of a reference type store references.

String x = null;

In this case, the initialization statement declares a variables “x”. “x” stores String reference. It is null here. First of all, null is not a valid object instance, so there is no memory allocated for it. It is simply a value that indicates that the object reference is not currently referring to an object.

时间你老了 2024-09-06 04:06:13

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是空类对象引用,但不是空指针,因为在Java中没有“指针”这样的东西,而是对类的引用而是使用对象,而Java中的null与类对象引用有关,所以你也可以将其称为“nullref”或“nullrefobj”,但是这个很长,所以就称为“null”。

在 C++ 中,您可以使用指针和 nullptr 值作为可选成员/变量,即没有值的成员/变量,如果没有值则等于 nullptr,那么 Java 中的 null 是如何实现的例如使用。

null in Java is like/similar to nullptr in C++.

Program in 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;
}

Same program in 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");
        }
    }
}

Now do you understand from the codes above what is null in Java? If no then I recommend you to learn pointers in C/C++ and then you will understand.

Note that in C, unlike C++, nullptr is undefined, but NULL is used instead, which can also be used in C++ too, but in C++ nullptr is more preferable than just NULL, because the NULL in C is always related to pointers and that's it, so in C++ the suffix "ptr" was appended to end of the word, and also all letters are now lowercase, but this is less important.

In Java every variable of type class non-primitive is always reference to object of that type or inherited and null is null class object reference, but not null pointer, because in Java there is no such a thing "pointer", but references to class objects are used instead, and null in Java is related to class object references, so you can also called it as "nullref" or "nullrefobj", but this is long, so just call it "null".

In C++ you can use pointers and the nullptr value for optional members/variables, i.e. member/variable that has no value and if it has no value then it equals to nullptr, so how null in Java can be used for example.

谁人与我共长歌 2024-09-06 04:06:13

在我看来,在 java 中查看 null 的一个有趣方法是将其视为并不表示缺少信息的东西,而只是将其视为可以分配给任何类型的引用的文字值。如果您考虑一下,如果它表示缺少信息,那么 a1==a2 为 true 是没有意义的(如果它们都被分配了 null 值),因为它们实际上可能指向任何对象(我们简单地不知道它们应该指向什么对象)...顺便说一下,java中null == null返回true。如果javaeg像SQL:1999那么null==null将返回unknown(SQL:1999中的布尔值可以采用三个值:true、false和unknown,但实际上unknown在实际系统中被实现为null)... http://en.wikipedia.org/wiki/SQL

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

牵你手 2024-09-06 04:06:13

JLS 简短而准确的回答正式回答了您的所有问题:

<块引用>

3.10.7。空文字

null 类型有一个值,即 null 引用,由
null 文字 null,由 ASCII 字符组成。

空文字始终是空类型。

仅分配分配给 null 的类型的引用。您没有为引用分配任何值(对象)。
这种分配特定于 JVM 将占用多少引用以及将在哪个内存区域中分配。

Short and precise answer which answers all your questions formally from JLS:

3.10.7. The Null Literal

The null type has one value, the null reference, represented by the
null literal null, which is formed from ASCII characters.

A null literal is always of the null type.

Only a reference of type which is assigned to null is allocated. You don't assign any value (object) to the reference.
Such allocation is specific to JVM how much reference will take and in which memory area it will be allocated.

清晨说晚安 2024-09-06 04:06:12

null 是任何东西的实例吗?

不,不存在 nullinstanceof 的类型。

15.20.2 类型比较运算符 <代码>实例

关系表达式:
    关系表达式引用类型实例

在运行时,如果 RelationalExpression 的值不为 nullinstanceof 运算符的结果为 true code> 并且引用可以转换为 ReferenceType,而不会引发 ClassCastException。否则结果为false

这意味着对于任何类型 ER,对于任何 E o,其中 o == null,< code>o instanceof R 始终为 false


“null”属于哪个集合?

JLS 4.1 类型和值的种类< /a>

还有一种特殊的null类型,即表达式null的类型,它没有名称。由于 null 类型没有名称,因此无法声明 null 类型的变量或强制转换为 null 类型。 null 引用是 null 类型表达式的唯一可能值。 null 引用始终可以转换为任何引用类型。实际上,程序员可以忽略 null 类型,并假装 null 只是一个可以是任何引用类型的特殊文字。


什么是空?

正如上面引用的 JLS 所说,实际上,您可以简单地假装它“只是一个可以是任何引用类型的特殊文字”。

在 Java 中,null == null(在其他语言中并非总是如此)。另请注意,根据合同,它也具有此特殊属性(来自 java.lang.Object):

public boolean equals(Object obj)

对于任何非 null 引用值 xx.equals(null)返回 false

它也是所有引用类型的默认值(对于具有它们的变量):

JLS 4.12.5 变量初始值

  • 每个类变量、实例变量或数组组件在创建时都会使用默认值进行初始化:
    • 对于所有引用类型,默认值为 null

如何使用它有所不同。您可以使用它来启用所谓的字段延迟初始化,其中字段的初始值为null,直到实际使用时,它会被“真实值”替换。 “值(计算起来可能很昂贵)。

还有其他用途。让我们举一个真实的例子 <代码>java.lang.System

public static Console console()

返回:系统控制台(如果有),否则null

这是一种非常常见的使用模式:null 用于表示对象不存在。

这是另一个用法示例,这次来自 java.io.BufferedReader

public String readLine() 抛出 IOException

返回:包含行内容的String,不包含任何行终止字符,如果行结束则返回null已达到流。

因此,在这里,readLine() 将为每一行返回 instanceof String,直到它最终返回 null 来表示结束。这允许您按如下方式处理每一行:

String line;
while ((line = reader.readLine()) != null) {
   process(line);
}

可以设计 API,以便终止条件不依赖于 readLine() 返回 null,但可以看到这种设计的好处是使事情变得简洁。请注意,空行没有问题,因为空行 "" != null

让我们再举一个例子,这次来自 java.util.Map

V get(对象键)

返回指定键映射到的值,如果此映射不包含该键的映射,则返回 null

如果此映射允许 null 值,则返回值 null 并不一定表明该映射不包含该键的映射;映射也可能显式地将键映射到 nullcontainsKey 操作可用于区分这两种情况。

这里我们开始了解使用 null 如何使事情变得复杂。第一条语句表示如果键未映射,则返回 null。第二条语句表示,即使键已映射,也可以返回 null

相反,java.util.Hashtable通过不允许 null 键和值使事情变得更简单;它的V get(Object key),如果返回null,则明确表示该键未映射。

您可以通读其余 API 并了解 null 的使用位置和方式。请记住,它们并不总是最佳实践示例。

一般来说,null作为一个特殊值来表示:

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

它在内存中是如何表示的?

在爪哇?与你无关。最好保持这种状态。


null 是一件好事吗?

现在这已经是主观的了。有人说 null 会导致许多本来可以避免的程序员错误。有人说,在像 Java 这样捕获 NullPointerException 的语言中,最好使用它,因为您会在程序员错误时快速失败。有些人通过使用空对象模式等来避免null

这是它本身就是一个很大的主题,因此最好将其作为另一个问题的答案进行讨论。

我将引用 null 的发明者本人的话来结束本文,CAR Hoare(因快速排序而闻名):

我称之为我的十亿美元错误。这是 1965 年 null 引用的发明。当时,我正在设计第一个综合类型系统面向对象语言(ALGOL W)中的引用。我的目标是确保所有引用的使用都绝对安全,并由编译器自动执行检查。但我无法抗拒放入 null 引用的诱惑,只是因为它很容易实现。这导致了无数的错误、漏洞和系统崩溃,在过去四十年中可能造成了数十亿美元的痛苦和损失。

此演示视频更深入;这是一款值得推荐的手表。

Is null an instance of anything?

No, there is no type which null is an instanceof.

15.20.2 Type Comparison Operator instanceof

RelationalExpression:
    RelationalExpression instanceof ReferenceType

At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast to the ReferenceType without raising a ClassCastException. Otherwise the result is false.

This means that for any type E and R, for any E o, where o == null, o instanceof R is always false.


What set does 'null' belong to?

JLS 4.1 The Kinds of Types and Values

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.


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".

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):

public boolean equals(Object obj)

For any non-null reference value x, x.equals(null) should 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

  • Each class variable, instance variable, or array component is initialized with a default value when it is created:
    • For all reference types, the default value is null.

How this is used varies. You can use it to enable what is called lazy initialization of 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).

There are also other uses. Let's take a real example from java.lang.System:

public static Console console()

Returns: The system console, if any, otherwise null.

This is a very common use pattern: null is used to denote non-existence of an object.

Here's another usage example, this time from java.io.BufferedReader:

public String readLine() throws IOException

Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached.

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:

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.

Let's take another example, this time from 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 of null does not necessarily indicate that the map contains no mapping for the key; it's also possible that the map explicitly maps the key to null. The containsKey operation may be used to distinguish these two cases.

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 also be returned.

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.

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 practice examples.

Generally speaking, null are used as a special value to signify:

  • 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?

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.

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):

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 a null 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.

The video of this presentation goes deeper; it's a recommended watch.

っ左 2024-09-06 04:06:12

null 是任何东西的实例吗?

不会。这就是为什么 null instanceof X 将为所有类 X 返回 false 的原因。 (不要被您可以将 null 分配给类型为对象类型的变量这一事实所迷惑。严格来说,分配涉及隐式类型转换;请参见下文。)

“null”属于哪个集合?

它是 null 类型中唯一的成员,其中 null 类型定义如下:

"还有一种特殊的 null 类型,即表达式 null 的类型,它没有名称。因为 null 类型有没有名称,无法声明 null 类型的变量或强制转换为 null 类型。 null 引用是 null 类型表达式的唯一可能值。实际上,程序员可以忽略 null 类型,并假装 null 只是一个可以是任何引用类型的特殊文字。” JLS 4.1

什么是空?

见上文。在某些上下文中,null 用于表示“无对象”或“未知”或“不可用”,但这些含义是特定于应用程序的。

它在内存中是如何表示的?

这是特定于实现的,您将无法在纯 Java 程序中看到 null 的表示形式。 (但是在大多数(如果不是全部)Java 实现中,null 表示为零机器地址/指针。)

Is null an instance of anything?

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.)

What set does 'null' belong to?

It is the one and only member of the null type, where the null type is defined as follows:

"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

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.

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.)

剧终人散尽 2024-09-06 04:06:12

什么是 null?

什么都没有。

null 是任何事物的实例吗?

不,因为它什么都不是。它不能是任何事物的实例。

null 属于哪个集合?

没有任何集合

它在内存中如何表示?

如果有一些引用指向它,例如:

Object o=new Object();

在堆内存中分配给新创建的对象的某些空间。 o 将指向内存中分配的空间。

现在 o=null;

这意味着现在 o 将不再指向对象的该内存空间。

What is null?

It is nothing.

Is null an instance of anything?

No as it is nothing It can't be instance of any thing.

What set does null belong to?

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.

Now o=null;

This means now o will not point to that memory space of object.

旧竹 2024-09-06 04:06:12

不,它不是任何东西的实例,instanceof 永远是 false。

No it's not the instance of anything, instanceof will always be false.

拥有 2024-09-06 04:06:12

Java(tm) 中的 Null

在 C 和 C++ 中,“NULL”是头文件中定义的常量,其值类似于:

    0

或:

    0L

或:

    ((void*)0)

取决于编译器和内存模型选项。严格来说,NULL 并不是 C/C++ 本身的一部分。

在Java(tm)中,“null”不是关键字,而是null类型的特殊文字。它可以转换为任何引用类型,但不能转换为任何原始类型,例如 int 或 boolean。空文字不一定具有零值。并且不可能强制转换为 null 类型或声明该类型的变量。

Null in Java(tm)

In C and C++, "NULL" is a constant defined in a header file, with a value like:

    0

or:

    0L

or:

    ((void*)0)

depending on the compiler and memory model options. NULL is not, strictly speaking, part of C/C++ itself.

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.

卷耳 2024-09-06 04:06:12

null 关键字是表示空引用的文字,不引用任何对象。 null 是引用类型变量的默认值。

也可以看看

null :Java Glossary

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.

Also maybe have a look at

null : Java Glossary

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文