How Generics Work
Put `int` between the angle brackets of `List<int>` and that choice does not evaporate when you hit Build: you can ask the running program what it was and get `System.Int32` back, something Java cannot do.
- ▸The
<int>inList<int>is still there when the program runs: reflection answersSystem.Int32, where Java erased it. - ▸Reference-type versions of a generic share one compiled body; each value-type version gets its own machine code.
- ▸
List<int>keeps raw ints inline in anint[]and never boxes;ArrayListboxes every value you add.
The previous topic ended on a warning: a value type used where an object is expected gets boxed, a hidden allocation on a line with no new. Generic collections are the standard cure, and to see why the cure works you first have to see what the angle brackets leave behind.
Write List<int> and the int is not a compile-time note that gets thrown away. Ask for it while the program runs:
Type t = typeof(List<int>); Console.WriteLine(t.GetGenericArguments()[0]); // System.Int32
The answer comes back System.Int32. The <int> is still bolted to the type, readable by reflection, available to serializers and anything else that needs to know what T actually is.
Java made the opposite call. There, new ArrayList<String>().getClass() and new ArrayList<Integer>().getClass() return the *same* class object: the <String> and <Integer> are erased before the program runs, so nothing can tell the two apart afterward. Same source shape, opposite answer. That one difference is the foundation the rest of this topic is built on.