我已经阅读了C# 和 Java 的比较,列表中的第一件事是“单根(统一)类型系统”。
你能描述一下单根(统一)类型系统的含义吗?
C# 有一个统一的类型系统。所有 C# 类型(包括 int 和 double 等原始类型)都继承自单个根object
类型。与类对象不同,这些原始类型是值类型。它们不是单独在堆上分配的,而是按值传递的。
当 C# 值类型(例如原始 int 或用户定义的结构)放置在参数集合中时,它存储在没有指针的密集数组中。这是可能的,因为 C# 为所需的每个不同参数“大小”进行了自定义参数实例化。这意味着当您实例化 C#List<int>
时,底层数组列表存储密集的 int 数组。
来源:http ://www.pin5i.com/showtopic-24376.html
Java也有几种基本类型(int、long、double、byte 等)——然而,它们的特殊之处在于它们不是面向对象的,并且它们不能使用语言本身来定义。它们是值类型,不是堆分配的,而是按值传递的。
资料来源:C# 和 Java 的比较 - 统一类型系统(维基百科)
同时,Java 也有面向对象的原始“包装器”类型(Integer、Long、Double、Byte 等),通常称为boxed
类型。这些是通过引用传递的堆分配对象,并且与上述原始类型并行存在。
在更新的 Java 版本中,基本类型会在必要时自动装箱为对象类型。这减轻了管理它们的大部分负担,但也可能导致细微的错误(另请参见自动装箱)。
与 C# 相比,在 Java 中,内置的 JDK Collections 框架始终管理对象指针的集合。为了使它们以向后兼容的方式参数化,Java 执行了一种称为类型擦除的技术,其中(在运行时)所有内容都被视为容器内的对象(在编译时执行参数化类型检查)。
这意味着您不能制作 Java List<int>
,您只能制作List<Integer>
. 而且,上面的列表实际上存储了一个指向装箱对象的指针数组Integer
,它的大小是 C# 版本的两倍,性能也大大降低。对于大多数用例来说,这种大小和性能的差异是无关紧要的。
在大小和性能相关的用例中,有两个选项可用:
这实际上也不适用于 C#,并非所有类型都派生自对象,就像其中 99.9% 一样。有几个非常奇怪的类型不能变成对象。唯一官方支持的是指针。还有 3 个不受支持,例如 TypedReference、RuntimeArgumentHandle 和第三个,它的名字让我无法理解。这 3 种类型与 C++/C 中具有可变长度方法的互操作一起使用。我不会太担心他们。