C#和Java中的null是什么?

14

像这样......它是像C++中的0吗?还是某种"特殊"对象?或者完全不同?

-- 编辑 --

我知道它是什么,问题是 - 它是如何做到的


2
一个简短的谷歌搜索就可以回答你的问题:例如http://mindprod.com/jgloss/null.html... - Valentin Rocher
1
点赞。这是一个好的关于海龟的问题。 - Johannes Schaub - litb
3
@Bishiboosh,这也可以是一个编程问题和答案的网站。 - Richard Szalay
我知道它是什么,问题在于“如何实现”... - argh
9个回答

18

由于您询问的是实现细节而不是语义,所以答案特定于给定的实现。

C# 中有三种“null”可能性:引用、指针和可空类型。

CLR 上的 C# 实现通过零位表示 null 引用。(其中位数是在运行特定版本 CLR 的托管指针大小)

不出所料,null 指针 同样也是这样表示。您可以在 C# 中进行演示,方法是制作一个不安全块,使其成为 void 的 null 指针,然后将其转换为 IntPtr,最后将 IntPtr 转换为 int(或在 64 位系统上转换为 long)。毫无疑问,您将得到零。

null 可空值类型 也是通过零来实现,但方式略有不同。 当您说:

int?j = null;

实际上我们创建的相当于:

struct NullableInt 
{
    int value;
    bool hasValue;
}

通过适当的访问器方法等,当其中一个被赋空值时,我们将整个对象用零位填充。该值为整数零,hasValue被填充为零,因此变为false;带有hasValue字段设置为false的可空类型被认为是null。

我不知道其他C# / CLI实现的具体实现细节。如果它们不同,我会感到惊讶;这是实现null的明显且合理的方式。但如果你对特定实现细节有疑问,你需要向了解你感兴趣的实现的人提问。


9

由于Java和C#运行在虚拟机上,因此用于表示null的物理方式并不重要,并且在不同的实现中可能不相同。

重要的是null的行为,如语言规范所定义的(有关详细信息,请参见Dan和MRFerocius的答案)。基本上,它是引用类型变量可以持有的特殊值,不能被取消引用。

顺便提一下,作为一个参考点,Java序列化规范使用单个字节值0x70来表示空引用。


这一切都是真的,但出于我的执着“求知欲”,对我来说,用什么物理方式表示空值很重要 ;) - argh
就像我所说的那样:这可能因每个JVM或.NET实现而异,作为一项实现细节,它并不是广泛发布的内容。 - Michael Borgwardt
哎呀,看到同样的东西会感到奇怪...而且它并没有广泛发表——我来这里是希望有人知道... - argh

7

Java语言规范4.1节

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


2

来自微软 MDSN:

null 关键字是一个字面量,表示一个空引用,即不引用任何对象。null 是引用类型变量的默认值。普通值类型不能为 null。但是,C# 2.0 引入了可空值类型。请参阅可空类型 (C# 编程指南)。


这解释了 null 关键字,但没有说明 null 引用是如何实现的。 - Will Eddins


1

它是一个特殊的引用(与0区分开来),指向空。


0

它相当于

#define NULL (void*)0

在C++中,基本上是零。

编辑: 由于我显然没有正确表达这个答案...

我的意思是这样的:

由于C#运行在虚拟机中,Michael Borgwardt所说的是正确的,我们不知道它在幕后是如何表示的。但是,如果您采用以下代码:

    unsafe static void Main(string[] args)
    {
        if (((void*)0) == null)
            Console.WriteLine("true");
        else
            Console.WriteLine("false");

        Console.ReadKey();
    }

并在启用“允许不安全代码”的情况下,在控制台应用程序中编译它,您将看到在C#中,null确实等于(void*) 0。


1
-1:在C#中,null不是值类型。这种说法充其量是一种过度简化。 - Brian
2
对于C++的严谨解释:在编译时,一个等于零的常量整数,在指针上下文中被求值,是一个空指针常量。也就是说,在代码中,零是表示空指针常量的方式,但在运行时,空指针并不等于零。 - Victor Nicollet
实际上,空指针是0。它指的是内存地址0x00000000:00000000,在Windows和Linux中都是空指针。再次阅读问题。在我看来,他理解了null的含义,他想知道如何实现它。而且它的实现方式与c++相同。 - FallenAvatar
1
@TJMonk: “哦,只是为了澄清一下,我这里只谈论C#。” — 那段是C++代码。C#中的null并不一定要指向0地址... - user47589
@yodaj007:我指的是C#如何定义null。我使用了C++代码,因为OP在他的问题中提到了C++,我假设他会理解C++片段。 - FallenAvatar
显示剩余3条评论

0

null是指向“无”的“引用”,因此它指向实际上不存在的东西。

额外信息:C#引用类型可以指向null(即:无),而像int这样的值类型不能指向null,尽管值类型可以在Nullable泛型引用类型中使用。


0

Null字面上意味着什么都没有。一些语言(如PHP)在特定情况下将null等同于0、false、空字符串等。Java和C#是强类型语言,因此不会发生任何“有帮助”的隐式转换。所以null字面上就是null或者什么都没有。Null只等于null,其他比较都不会返回true。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接