Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a unified type system?

I've read a comparison of C# and Java and the first thing on the list is "Single-root (unified) type system".

Can you describe what a single-root (unified) type system means?

like image 585
Tom Pažourek Avatar asked Nov 20 '10 14:11

Tom Pažourek


People also ask

Is C# a Unified type system?

C# has a unified type system. All C# types, including primitive types such as int and double, inherit from a single root object type. Unlike class objects, these primitive types are value-types. They are not separately heap-allocated, and they are passed by value.

What is C# type system?

C# provides a standard set of built-in types. These represent integers, floating point values, Boolean expressions, text characters, decimal values, and other types of data. There are also built-in string and object types. These types are available for you to use in any C# program.

What is type system in Java?

Java's type system involves not only classes and primitive types, but also other kinds of reference type that are related to the basic concept of a class, but which differ in some way, and are usually treated in a special way by javac or the JVM.


1 Answers

C# has a unified type system. All C# types, including primitive types such as int and double, inherit from a single root object type. Unlike class objects, these primitive types are value-types. They are not separately heap-allocated, and they are passed by value.

When a C# value type (such as a primitive int, or user-defined struct) is placed in a parametric collection, it is stored in a densely packed array with no pointers. This is possible because C# makes a custom parametric instantiation for each different parametric 'size' that is required. This means when you instantiate a C# List<int>, the underlying array list stores densely packed arrays of int.

Source: http://www.pin5i.com/showtopic-24376.html

Java also has several primitive types (int, long, double, byte, etc) - however, they are special in that they are not object-oriented and they could not have been defined using the language itself. They are value types, not heap allocated, and passed by value.

Source: Comparison of C# and Java - Unified type system (Wikipedia)

At the same time, Java also has object-oriented primitive "wrapper" types (Integer, Long, Double, Byte, etc), often called boxed types. These are heap allocated objects which are passed by reference, and exist in parallel to the primitive types mentioned above.

In more recent versions of Java, primitive types are automatically boxed into object types when necessary. This relieves most of the burden of managing them but it can also cause subtle bugs (see also auto-boxing).

In contrast to C#, in Java, the built-in JDK Collections framework always manages collections of object pointers. In order to make them parametric in a backward-compatible fashion, Java performs a technique called type-erasure, where (during runtime) everything is treated as an object inside the container (parameterised type checks are performed at compile time).

This means that you cannot make a Java List<int>, you can only make List<Integer>. And, the list above actually stores an array of pointers to boxed Integer objects, which is double the size and substantially less performant than the C# version. For most use cases, this difference in size and performance is irrelevant.

In use cases where size and performance are relevant, there are two options available:

  1. When you know the size of your list in advance, use an array of native types, for example int[]. Arrays of native types are packed in memory so they consume A LOT less memory and are more performant.
  2. When you do not know the size of your list in advance, use some 3rd party list implementation that wraps the native array, making it possible to add elements to it after creation (some examples: Trove, Colt, Fastutil, Guava).
like image 133
Neeme Praks Avatar answered Sep 21 '22 21:09

Neeme Praks