c#、java中null是什么?

发布于 2024-08-17 02:29:52 字数 129 浏览 4 评论 0原文

就像...是像 C++ 中的 0 吗?或者它是一些“特殊”的物体?或者也许是完全不同的东西?

-- 编辑 --

我知道它是什么,问题是 - 它是如何完成的

Like... is it 0 like in C++? Or is it some "special" object? Or maybe something totally different?

-- EDIT --

I do know what it is, the question is rather - how it's done

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

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

发布评论

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

评论(9

烦人精 2024-08-24 02:29:52

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

在 C# 中,“null”可以是三种情况。引用、指针和可为 null 的类型。

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

毫不奇怪,空指针以相同的方式表示。您可以在 C# 中演示这一点,方法是创建一个不安全块,创建一个指向 void 的空指针,然后将其转换为 IntPtr,然后将 IntPtr 转换为 int(或 long,在 64 位系统上)。果然,你会得零分。

null 可空值类型也由零实现,尽管方式不同。当你说

int 时? j = 空;

我们实际创建的道德等价物是:

struct NullableInt 
{
    int value;
    bool hasValue;
}

使用适当的访问器方法,等等。当其中一项被指定为 null 时,我们只需用零位填充整个内容。该值为整数零,hasValue 被填充为零,因此变为 false; hasValue 字段设置为 false 的可空类型被视为空。

我不知道 C# / CLI 的其他实现的实现细节是什么。如果它们不同,我会感到惊讶;这是实现空值的明显且明智的方法。但是,如果您对特定的实现细节有疑问,则必须询问了解您感兴趣的实现的人。

Since you're asking about implementation details, rather than semantics, the answer is specific to a given implementation.

There are three things in C# that "null" can be. A reference, a pointer, and a nullable type.

The implementation of C# on the CLR represents a null reference by zero bits. (Where the number of bits is the appropriate size to be a managed pointer on the particular version of the CLR that you're running.)

Unsurprisingly, a null pointer is represented the same way. You can demonstrate this in C# by making an unsafe block, making a null pointer to void, and then converting that to IntPtr, and then converting the IntPtr to int (or long, on 64 bit systems). Sure enough, you'll get zero.

A null nullable value type is also implemented by zeroes, though in a different way. When you say

int? j = null;

what we actually create is the moral equivalent of:

struct NullableInt 
{
    int value;
    bool hasValue;
}

With appropriate accessor methods, and so on. When one of those things is assigned null, we just fill the whole thing with zero bits. The value is the integer zero, and the hasValue is filled with zeroes and therefore becomes false; a nullable type with the hasValue field set to false is considered to be null.

I do not know what the implementation details are on other implementations of C# / the CLI. I would be surprised if they were different; this is the obvious and sensible way to implement nulls. But if you have questions about a specific implementation detail, you'll have to ask someone who knows about the implementation you're interested in.

别理我 2024-08-24 02:29:52

由于 Java 和 C# 运行在虚拟机上,因此物理上使用什么来表示 null 并不重要,而且在不同的实现中它也不一定相同。

重要的是 null 的行为,如语言规范中所定义(有关详细信息,请参阅 Dan 和 MRFeocius 的回答)。基本上,它是引用类型的变量可以保存的特殊值,并且不能取消引用。

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

Since Java and C# run on virtual machines, it does not matter what is used physically to represent null, and it is not necessarily the same across implementations.

What matters is the behaviour of null, as defined in the language specification (see Dan's and MRFerocius' answers for details). Basically, it is a special value that variables of reference type can hold, and which cannot be dereferenced.

BTW, as a reference point, the Java serialization spec use a single byte value 0x70 to represent a null reference.

一身骄傲 2024-08-24 02:29:52

Java 语言规范第 4.1 节

还有一种特殊的 null 类型,
表达式 null 的类型,其中有
没有名字。因为null类型没有
名称,无法声明
null 类型的变量或要强制转换的变量
到 null 类型。空引用
是唯一可能的值
null 类型的表达式。空值
引用始终可以转换为任何
参考类型。在实践中,
程序员可以忽略 null 类型
并假装 null 只是一个
可以是任何特殊文字
参考类型。

Java Language Specification section 4.1:

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.

枫以 2024-08-24 02:29:52

来自 Microsoft MDSN:

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

From Microsoft MDSN:

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. Ordinary value types cannot be null. However, C# 2.0 introduced nullable value types. See Nullable Types (C# Programming Guide).

轮廓§ 2024-08-24 02:29:52

它是一个特殊的引用(以区别于 0),它不指向任何内容。

It is a special reference ( to differentiate it from 0 ) which point to nothing.

荆棘i 2024-08-24 02:29:52

null 是对任何内容的“引用”,因此它实际上指向任何内容。

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

null is a "reference" to nothing, so it points to literally nothing.

Additional info: A C# reference type can point to null (i.e.: nothing), a value type like int cannot point to null, although a valuetype can be used in the Nullable generic reference type.

-小熊_ 2024-08-24 02:29:52

空实际上就是什么都没有。某些语言(例如 PHP)在某些情况下会将 null 等同于 0、false、空字符串等。 Java 和 C# 是强类型语言。因此,这些“有用的”隐式转换都不会发生。所以 null 实际上就是 null 或什么都没有。 Null 只等于 null。没有其他比较会返回 true。

Null is literally nothing. Some languages like PHP will equate null to 0, false, empty string, etc. under certain circumstances. Java and C# are strongly typed languages. Therefore none of those "helpful" implicit conversions take place. So null is literally null or nothing. Null is only equal to null. No other comparison will return true.

宁愿没拥抱 2024-08-24 02:29:52

它相当于

#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。

its equivalent to

#define NULL (void*)0

in c++. So basically, yes, it is zero.

EDIT:
Since I apparently didn't word this answer anywhere near correctly...

What I meant is this:

As C# runs in a VM, what Michael Borgwardt said is correct, we don't know how its represented behind the scenes. However, if you take the following code:

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

        Console.ReadKey();
    }

and compile it in a console app, with "Allow unsafe code" enabled, you will see that in c#, null is indeed equal to (void*) 0.

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