当前位置: 首页 > 面试题库 >

Java和C#中的原始类型是否不同?

董光霁
2023-03-14
问题内容

我正在将代码从Java手动转换为C#,并在原始类型(我称之为)方面苦苦挣扎(请参见例如,自动装箱和拆箱在Java和C#中的行为是否不同)。从答案中我了解到double(C#)和Double(C#)是等效的,并且double(C#)也可以在容器中使用,例如,作为Dictionary中的键。但是,double(Java)不能在HashMap这样的容器中使用,这就是为什么将其自动装箱到Double(Java)。

  1. double(C#)一个原始或对象?
  2. 如果它是原始语言,那么它的行为与double(Java)不同吗?

double(C#)除非设置为null,否则不能设置为null nullable

  1. double?(C#)相当于Double(Java)的?它们都被称为对象吗?

(在此讨论中使用术语“一流对象”有用吗?)


问题答案:

C#和Java都具有原始(或“值”)类型:int,double,float等。

但是,此后C#和Java趋于分裂。

Java具有 所有原始类型的 包装类类型(在Java中是一个小的有限集),可将它们视为对象。
double/Doubleint/Integerbool/Boolean等。这些包装类型是引用类型(读:类),并且同样地,null是分配给这样的类型化的表现形式/变量的有效值。Java的最新版本(1.5
/ 5 +)在原语中将隐式强制添加到其对应的包装器中。

// Java
Boolean b = true; // implicit conversion boolean -> Boolean (Java 5+)
Boolean b = null; // okay, can assign null to a reference type
boolean n = null; // WRONG - null is not a boolean!

C#没有提供这种直接包装的1部分内容,因为C#通过结构支持 无限的一组值类型 ;相反,C#通过引入包装器类型来处理“空值类型”
。另外,C#和Java一样,具有从值类型到的隐式转换,其限制是T本身不是“不能为null的类型”。Nullable<T>T``Nullable<T>

// C#
Nullable<bool> b = true; // implicit conversion bool -> bool?
bool? b = true;          // short type syntax, implicit conversion
bool? b = null;          // okay, can assign null as a Nullable-type
bool b = null;           // WRONG - null is not a bool

请注意,这Nullable<T>也是一个值类型,因此遵循关于何时/是否值“在堆栈上”的标准结构规则。

回应评论:

绝对正确,作为值类型的Nullable确实可以使其 在某些情况下 具有更紧凑的内存占用
因为它可以避免引用类型的内存开销:什么是Nullable
的内存占用 。但是,与非Nullable类型相比,它仍然需要更多的内存,因为它必须记住该值是否为null。根据对齐问题和VM实施,此对象可能小于或等于“完全”对象。另外,由于对C#/
CLR中的值进行了修正,请考虑必须执行的所有提升操作:

// C#
object x = null;
x = (bool?)true;
(x as bool?).Value // true

文章Java技巧130:你知不知道你的数据的大小?讨论引用类型的内存消耗(在Java中)。需要注意的一件事是,JVM内部具有专用版本的Array,每个基本类型和Object都有一个专门的版本(但是,请注意,本文包含一些
误导性声明
)。注意对象(相对于基元)如何引起额外的内存开销和字节对齐问题。但是,C#可以将优化数组的情况扩展为Nullable<T>类型,而JVM具有有限的特殊情况,因为JVM
Nullable<T>本身仅仅是结构类型(或“原始”)。

但是,对象仅需要较小的固定大小即可在可变插槽中维护对其的“引用”。Nullable<LargeStruct>另一方面,类型可变的插槽必须具有空间LargeStruct+Nullable(插槽本身可能在堆上)。请参见C#概念:值与引用类型。请注意,在上面的“提升”示例中,变量的类型是objectobject在C#中是“根类型”(引用类型和值类型的父),而
不是 专用值类型。

1 C#语言为原始类型/公用类型支持一组固定的 别名 ,这些 别名
允许访问“友好的小写”类型名称。例如,doubleSystem.Doubleint的别名System.Int32。除非不同的Double类型是在范围进口,double并且Double将参考在C#相同的类型。我建议使用别名,除非有理由这样做。



 类似资料:
  • 问题内容: Java中的原始类型是什么? 基本类型和引用类型之间有什么区别? Java有多少种原始类型,它们是什么? 问题答案: 在Java中,每个变量都有在源代码中声明的类型。类型有两种:引用类型和原始类型。引用类型是对对象的引用。基本类型直接包含值。有8种原始类型: *Byte *Short *Integer *Long *Scorch *Floating *Double *Boolean v

  • 问题内容: 在Java中,原始类型和数组是否具有包含包? 可能不是,但是只是想确定一下。 问题答案: 简单答案 让我们测试一下: 输出: 空 null 不,他们不:-) 基本类型 原始类是没有包的特殊构造。供参考,请参阅的来源,别名为: 如您所见,原始类是通过package-private和native机制加载的: 并投射到(我想为了启用自动装箱) 包装器类型及其原始类型 顺便说一句:每个包装器类

  • 我试着搜索像Multi-raw类型的东西,但我没有找到任何东西。 我该怎么做?

  • 问题内容: 我是Kotlin的新手,正在玩数据类型。我选择了一个类型,然后尝试通过说来将其强制转换为a ,这在Java中是有效的(从语法上讲,但这是正确的)。但是,此操作失败,表示无法将Int强制转换为Double。我假设这是因为它是基于Integer类而不是原始的int数据类型构建的。我是正确的,最有价值的方法是什么?有一个功能,但这似乎效率低下且笨拙。 问题答案: 我花了一个类型,然后试图将它

  • 我是科特林的新手,我在玩数据类型。我取了一个<code>Int</code>类型,然后尝试将其转换为<code>Double</code>,将<code>num表示为Double>/code,这是一个在java中有效的调用(非语法上,但你明白了)。然而,这失败了,表示Int不能强制转换为Double。我假设这是因为它是基于Integer类而不是原始int数据类型构建的。我说得对吗?什么是最有效的价

  • 问题内容: 什么是原始类型? 问题答案: Java语言规范对原始类型的定义如下: JLS 4.8原始类型 原始类型定义为以下之一: 通过采用通用类型声明的名称而没有随附的类型参数列表形成的引用类型。 数组类型,其元素类型为原始类型。 未从的超类或超接口继承static的原始类型的非成员类型。RR 这是一个例子说明: 这是参数化类型(JLS 4.5)。通常,通俗地简称MyType为这种类型是很常见的