Java

So we now know that generic types in Java do not preserve that type information at runtime. What is the consequence of this? Let’s once again consider the following program:

  1. import java.util.ArrayList;
  2. class Main {
  3. public static void printLen(ArrayList<?> list) {
  4. System.out.println(list.size());
  5. }
  6. public static void main(String[] args) {
  7. ArrayList<Integer> ints = new ArrayList<Integer>();
  8. ints.add(1);
  9. ints.add(2);
  10. ints.add(3);
  11. ArrayList<String> strs = new ArrayList<String>();
  12. strs.add("Hello");
  13. strs.add("world");
  14. printLen(ints);
  15. printLen(strs);
  16. }
  17. }

The above program defines two variables using the generic list type, ArrayList:

  • ints: a list of Integer values
  • strs: a list of String values

We know that at runtime both ints and strs lost their type information and each become ArrayList<Object>. Does this mean it is possible to add a String value to the ints list at runtime? Follow the instructions below to find out:

  1. Launch the container:

    1. docker run -it --rm go-generics-the-hard-way
  2. Compile the above program:

    1. javac -g ./05-internals/java/main.java
  3. Load the above program into the Java debugger:

    1. jdb -sourcepath ./05-internals/java -classpath ./05-internals/java Main
  4. Set a breakpoint so the debugger will pause execution after the ints list has been defined and values added to it:

    1. stop at Main:30
  5. Run the program:

    1. run

    which should stop when the above breakpoint is hit:

    1. Breakpoint hit: "thread=main", Main.main(), line=30 bci=35
    2. 30 ArrayList<String> strs = new ArrayList<String>();
  6. Now that it is loaded into memory, let’s print the contents of the ints list:

    1. print ints
    1. ints = "[1, 2, 3]"
  7. Try adding the string “Hello” to the ints list:

    1. eval ints.add("Hello")
    1. ints.add("Hello") = true

    It looks like it worked!

  8. Print the contents of ints again to verify it now contains three numbers and a string:

    1. print ints
    1. ints = "[1, 2, 3, Hello]"

    This is the consequence of type erasure. At runtime Java provides no type safety for its generic types.

  9. Type quit to exit the debugger.

  10. Type exit to stop and remove the container.

In other words, generics in Java are purely a compile-time convenience feature. How does .NET stack up? Keep reading and find out.


Next: .NET