I've defined a method in a class:
public void setCollection(Collection<MyClass>);
and in another class
public void setCollection(Collection<OtherClass>);
(and really, lots of similar classes)
All are in classes with the same superclass, and I have a method in a support-class where I want to call this method and set it with items of the correct class type. Now, I can get that I'm setting a Collection by doing
Method setter = ...;
Class<?> paramClass = setter.getParameterTypes()[0]; // Is Collection in this case
if(paramClass.equals(Collection.class)) {
HashSet col = new HashSet();
// fill the set with something
setter.invoke(this, col);
}
But how do I figure out what class the objects in this collection should belong to?
Cheers
Nik
Method.getGenericParameterTypes();
returns an array of Types which the parameter accepts. Complexity increases exponentially from there.
In your specific case, this would work:
Method m = Something.class.getMethod("setCollection", Collection.class);
Class<?> parameter = (Class<?>) ((ParameterizedType) m.getGenericParameterTypes()[0]).getActualTypeArguments()[0];
But there are a lot of potential gotchas there, depending on how the parameter was declared. If it is a simple as in your example, great. If not, then there are a bunch of types you have to account for, both in the getGenericParameterTypes() method and in the getActualTypeArguments() method. It gets very hairy and ugly very fast.
I would consider moving the setCollection methods out into their own classes and then doing something more like this (you can change it to create the whole collection at once instead of doing it as an element at a time).
This gets rid of reflection and ensures that it it typesafe at compile time. I could be misunderstanding what it is you are trying to do, but I think I got it. The "init" method would be the helper method (at least if I understand what you are aimng for).
public class Main
{
public static void main(String[] args)
{
List<Car> car;
List<Bar> bar;
car = new ArrayList<Car>();
bar = new ArrayList<Bar>();
init(car, new CarCreator());
init(bar, new BarCreator());
}
private static <T> void init(final List<T> list,
final Creator<T> creator)
{
for(int i = 0; i < 10; i++)
{
final T instance;
instance = creator.newInstance(i);
list.add(instance);
}
}
}
interface Foo
{
}
class Bar implements Foo
{
}
class Car implements Foo
{
}
interface Creator<T>
{
T newInstance(int i);
}
class BarCreator
implements Creator<Bar>
{
public Bar newInstance(final int i)
{
return (new Bar());
}
}
class CarCreator
implements Creator<Car>
{
public Car newInstance(final int i)
{
return (new Car());
}
}
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