Why does this code run without any exceptions?
public static void main(String args[]) { List<Integer> a = new ArrayList<Integer>(); try { a.getClass() .getMethod("add", Object.class) .invoke(a, new Double(0.55555)); } catch (Exception e) { e.printStackTrace(); } System.out.println(a.get(0)); }
Reflection allows instantiation of new objects, invocation of methods, and get/set operations on class variables dynamically at run time without having prior knowledge of its implementation.
Reflection is an API that is used to examine or modify the behavior of methods, classes, and interfaces at runtime. The required classes for reflection are provided under java.lang.reflect package which is essential in order to understand reflection.
Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
Generics are a compile-time thing. At runtime, a regular ArrayList
, without any additional check, is used. Since you're bypassing the safety checks by using reflection to add elements to your list, nothing can prevent a Double
from being stored inside your List<Integer>
. Just like if you did
List<Integer> list = new ArrayList<Integer>(); List rawList = list; rawList.add(new Double(2.5));
If you want your list to implement type checks at runtime, then use
List<Integer> checkedList = Collections.checkedList(list, Integer.class);
Because of the type erasure - there are no runtime checks for the generics, during compilation type parameters are removed: Java generics - type erasure - when and what happens.
You may be surprised, but you don't need to use reflection to add a Double
to a List<Integer>
:
List<Integer> a = new ArrayList<Integer>(); ((List)a).add(new Double(0.555));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With