Java – Definitions of “primitive”, “value type”, “struct”, “class”, “wrap” in Java and C#


I have been trying to understand the use of "primitives" in Java and C# and the difference between them (if any). I have asked a series of questions on SO and some of the answers seem to confuse the issue rather than clarify it. Some answers (and some MS documentation) appear to provide contradictory statements. From SO

and from MS:,lightweight%29.aspx
– "structs are very similar to classes"
– "the Int32 class wraps the int data type"
– "On the other hand, all primitive data types in C# are objects in the System namespace. For each data type, a short name, or alias, is provided. For instance, int is the short name for System.Int32".

My confusion lies largely with C# (I have programmed java for some while).

EDIT The following paragraph has been confirmed to be correct by @Jon Skeet

  • Java has two types (primitive and class). The words "value type" could be a synonym for primitive (although not widely used) and "reference type" for class. Java "wraps" primitives (int) in classes (Integer) and these classes have the complete power of any other class (can be null, used in collections, etc.)

EDIT @Jon has given a very clear statement on C# so I will delete my suggested truths and refer to his answer.

Further question: Is there a consensus on what the actual use of these terms should be? If there is a consensus I'd be very grateful for it spelt out explicitly. Otherwise I assume the terminology is muddled and therefore of limited use.

SUMMARY Thanks for very clear answers. There is a consensus (see accepted answer from @Jon) among those who really understand this and the MS docs are consistent (although they refer to Java in places and I misread these for C#)

Best Solution

The first bullet point is correct.

The second is not: the primitive types in .NET are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single. A struct cannot usually be set to null, but there are also nullable value types (Nullable<T>). These are still value types, but there's syntactic sugar in C# to equate "null" with "the null value for the type", which for a nullable value type is an instance where HasValue returns false.

int and System.Int32 are exact synonyms in C#. The former is just an alias for the latter. They compile to exactly the same code.

In C#, classes and interfaces are always reference types. Structs and enums are value types - but there is a boxed equivalent of every struct (other than Nullable<T> which is handled differently by the CLR in terms of boxing). The boxed types don't have separate names, and can't be referred to explicitly in C# (although they can be in C++/CLI). There is no separate wrapper class equivalent like java.lang.Integer in .NET; it would be problematic to introduce such classes as you can create your own value types in .NET, unlike in Java.

For more information on reference types and value types, see my article about it.