The answer is pretty simple. Generics are compile-time components to ensure compile-time compatibility. Generics disappeared after compilation and therefore do not exist in Runtime anymore.
How Object listABC returns a List , (List) Test.listABC(); does not throw an exception because it is valid, since it actually returns a List .
you can assign it to List<Long> listLong because at run time listLong no longer knows about this Long generic.
As a result, this, although it looks wrong, is a valid executable code.
also the only reason this works is because the PrintStream#println(Object) method exists, otherwise you will get an Exception because you are trying to call it with the wrong type, as you can see in the following example.
static Object listABC() { List<Test> listOfABC = new ArrayList<>(); listOfABC.add(new Test()); return listOfABC; } public static void main(String[] args) throws java.lang.Exception { List<Long> listLong = (List) Test.listABC(); System.out.println(listLong.get(0)); test(listLong.get(0)); } private static void test(Long longvalue) { System.out.println("TEST"); }
O / p
ABC@19e0bfd Exception in thread "main" java.lang.ClassCastException: ABC cannot be cast to java.lang.Long at ABC.main(ABC.java:19)
source share