How to implement generic functions in Java?
According to my understanding, the following generic functions in Java:
public static <T> T f(T x) { Integer[] arr = new Integer[4]; T ret = (T) arr[2]; return ret; }
Compiled into the following form (because it is unbounded):
public static Object f(Object x) { Integer[] arr = new Integer[4]; Object ret = (Object) arr[2]; return ret; }
However, when I run the following statement, the compiler can evaluate the return value as an integer How does the compiler calculate it?
Integer i = f(new Integer(4));
The functions of the above statements should not be written as follows:
public static <T extends Integer> T f(T x) { Integer[] arr = new Integer[4]; T ret = (T) arr[2]; return ret; }
Solution
Generics use type erasure This basically means that generics are just implicit, so when you do this:
List<Integer> ...
No different from a normal list, it may contain integers or any real You just tell java to convert get () to integers (and other things) Types are not retained at runtime at all (primary)
Arrays are different. Arrays are called covariates This means that their types are preserved at run time So you can do:
List<Integer> list1 = new ArrayList<Integer>(); list2 = (List<String>)list1; list2.add("hello");
This is perfectly legal and will compile and run However:
Integer[] arr1 = new Integer[10]; String[] arr2 = (String[])arr1; // compiler error
But it is also more subtle than that
Integer[] arr1 = new Integer[10]; Object[] arr2 = (Object[])arr1; arr2[5] = "hello"; // runtime error!
About your function when you write:
public static <T> T f(T x) { Integer[] arr = new Integer[4]; T ret = (T) arr[2]; return ret; }
You tell the compiler to export t from parameters as parameter type and return type So when you pass in integer, the return type is integer When you call:
Integer i = f(new Integer(4));
The compiler just follows your instructions The function does take and return an object in compiled form, but it just does this:
Integer i = (Integer)f(new Integer(4));
Implicit
Like the list example above, nothing prevents you from having f () return anything you like, rather than something based on parameterized types