I have this class:
public class TestSubject {
public TestSubject(List<Integer> list) {
}
}
I'm instantiating it like this and somehow it's working, even though I'm inserting an ArrayList<String>
into a constructor that accepts List<Integer>
:
List<String> strings = new ArrayList<>();
strings.add("foo");
Constructor<TestSubject> constructor = TestSubject.class.getConstructor(List.class);
TestSubject test = constructor.newInstance(strings);
This is what I see after instantiation:
How can this be possible?
Also, how can I make sure from the instantiation code that the correct type of list is being used?
You can do this as follows but have to give up on generics for the list container. List<List> listOfMixedTypes = new ArrayList<List>(); ArrayList<String> listOfStrings = new ArrayList<String>(); ArrayList<Integer> listOfIntegers = new ArrayList<Integer>(); listOfMixedTypes.
Any Collection can be passed as an argument to the constructor as long as its type extends the type of the ArrayList , as String extends Object .
Using a Copy Constructor: Using the ArrayList constructor in Java, a new list can be initialized with the elements from another collection. Syntax: ArrayList cloned = new ArrayList(collection c); where c is the collection containing elements to be added to this list.
This is happening due to type erasure. As <Integer>
will be erased and it will be List
only. However you are creating the instance with reflection and at runtime it will not check the type of the List
.
Here type of the list is checked during compile time if you create it with new
but in this case you skipped the compile time check and during runtime it is valid because of type erasure.
In your case there is no direct way other than checking the type of elements manually in the constructor.
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