what is so hard technically to include primitive types when talking about Generics ?
In Java's case, it's because of the way generics work. In Java, generics are a compile-time trick, that prevents you from putting an Image
object into an ArrayList<String>
. However, Java's generics are implemented with type erasure: the generic type information is lost during run-time. This was for compatibility reasons, because generics were added fairly late in Java's life. This means that, run-time, an ArrayList<String>
is effectively an ArrayList<Object>
(or better: just ArrayList
that expects and returns Object
in all of its methods) that automatically casts to String
when you retrieve a value.
But since int
doesn't derive from Object
, you can't put it in an ArrayList that expects (at runtime) Object
and you can't cast an Object
to int
either. This means that the primitive int
must be wrapped into a type that does inherit from Object
, like Integer
.
C# for example, works differently. Generics in C# are also enforced at runtime and no boxing is required with a List<int>
. Boxing in C# only happens when you try to store a value type like int
in a reference type variable like object
. Since int
in C# inherits from Object
in C#, writing object obj = 2
is perfectly valid, however the int will be boxed, which is done automatically by the compiler (no Integer
reference type is exposed to the user or anything).