Java和C#中的原始类型是否不同? [英] Are primitive types different in Java and C#?

查看:85
本文介绍了Java和C#中的原始类型是否不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将代码从Java手动转换为C#,并在原始类型(我称之为)方面挣扎(例如,参见

I am manually converting code from Java to C# and struggling with (what I call) primitive types (see, e.g. Do autoboxing and unboxing behave differently in Java and C#). From the answers I understand that double (C#) and Double (C#) are equivalent and double (C#) can also be used in containers, e.g. as a key in a Dictionary. However, double (Java) cannot be used in containers like HashMap which is why it is auto-boxed to Double (Java).

  1. double (C#)是基元还是对象?
  2. 如果它是原始语言,那么它的行为与 double (Java)不同吗?
  1. Is double (C#) a primitive or an object?
  2. If it's a primitive what makes it behave differently from double (Java)?

double (C#)不能设置为null,除非将其设置为 nullable .

double (C#) cannot be set to null unless it is made nullable.

  1. double?(C#)是否等于 Double (Java)?它们都被称为对象吗?
  1. Is double? (C#) equivalent to Double (Java)? Are they both referred to as objects?

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

(Is the use of the term "first-class object" useful in this discussion?)

推荐答案

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

Both C# and Java have primitive (or "value") types: int, double, float, etc...

但是,在此之后,C#和Java趋于分裂.

However, after this C# and Java tend to divide.

Java具有所有原始类型(这是Java中的一个很小的有限集)的包装器类类型,可将它们视为对象. double/Double int/Integer bool/Boolean 等.这些包装器类型是引用类型(阅读:类),并且例如, null 是一个有效值,可分配给此类键入的表达式/变量.Java的最新版本(1.5/5 +)将从原始的隐式强制添加到其对应的包装器中.

Java has wrapper Class types for all of the primitive types (which is a small finite set in Java) which allows them to be treated as Object. double/Double, int/Integer, bool/Boolean, etc. These wrapper types are reference-types (read: Classes) and, as such, null is a valid value to assign to such typed expressions/variables. Recent versions of Java (1.5/5+) add in implicit coercions from primitives to their corresponding wrapper.

// 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#通过 Nullable<来处理空值类型".T> 包装器类型.另外,像Java一样,C#具有从值类型 T Nullable< T> 的隐式转换,但限制是T本身不是不能为null的类型"./p>

C# doesn't provide a such a direct wrapping1 - in part, because C# supports an infinite set of value types via structures; rather, C# handles "nullable value types" by introduction of a Nullable<T> wrapper type. In addition C#, like Java, has implicit conversions from the value type T to Nullable<T>, with the restriction that T is "not a nullable type" itself.

// 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> 也是一种值类型,因此遵循有关何时/是否值在堆栈上的标准结构规则.

Note that Nullable<T> is also a value type and thus follows the standard structure rules for when/if a value is "on the stack" or not.

针对评论:

绝对正确,作为值类型的Nullable确实使其在某些情况下具有更紧凑的内存占用量 ,因为它可以避免引用类型的内存开销:

Absolutely correct, Nullable being a value-type does allow it to have a more compact memory footprint in certain cases as it can avoid the memory overhead of a reference type: What is the memory footprint of a Nullable<T>. However it still requires more memory than the non-Nullable type because it has to remember if the value is, well, null, or not. Depending upon alignment issues and VM implementation, this may or may not be significantly less than a "full" object. Also, since values in C#/CLR are reified, consider any lifting operations that must be performed:

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

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

The article Java Tip 130: Do you know your data size? talks about reference type memory consumption (in Java). One thing to note is that the JVM has specialized versions of Arrays internally, one for each primitive type and for Objects (however, please note that this article contains some misleading statements). Note how the Objects (vs. primitives) incur extra memory overhead and the byte alignment issues. C# however, can extend the optimized-array case for Nullable<T> types vs. the the limited special-cases the JVM has because Nullable<T> is itself just a structure type (or "primitive").

但是,对象只需要较小的固定大小即可在可变插槽中维护对其的引用".另一方面,类型为 Nullable< LargeStruct> 的可变插槽必须具有用于 LargeStruct + Nullable 的空间(插槽本身可以在堆上).请参见 C#概念:值与引用类型.请注意,在上面的提升"示例中,变量的类型是 object : object 是C#中的根类型"(引用类型和值类型均是父类型),并且不是专门的值类型.

However, an Object, only requires a small fixed size to maintain a "reference" to it in a variable slot. A variable slot of type Nullable<LargeStruct> on the other hand, must have space for LargeStruct+Nullable (the slot itself may be on the heap). See C# Concepts: Value vs Reference Types. Note how in the "lifting" example above the variable is of type object: object is the "root type" in C# (parent of both reference types and value types) and not a specialized value type.

1 C#语言支持一组固定的别名,用于原始/通用类型,这些类型允许访问友好的小写"类型名称.例如, double System.Double 的别名,而 int System.Int32 的别名.除非在作用域中导入了不同的 Double 类型,否则 double Double 将在C#中引用相同的类型.除非有其他理由,否则我建议使用别名.

1 The C# language supports a fixed set of aliases for primitive/common types that allow access to "friendly lowercase" type names. For instance, double is an alias for System.Double and int is an alias for System.Int32. Unless a different Double type is imported in scope, double and Double will refer to the same type in C#. I recommend using the aliases unless there is a reason to do otherwise.

这篇关于Java和C#中的原始类型是否不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆