Oh my. Reflection on generics. That's not always nice.
So, here goes.
As can be easily found, it is possible to determine the actual type of a generic class at runtime.
And in the code we get a number of lists<>... and we want to sort them by class hierarchy (so, String extends Object, and thus List<String> should go after List<Object>)
Our compare method then needs to look like this:
compare( List left, List right) {
Type type = left.getClass().getGenericSuperclass()
if(type instanceof ParameterizedType) {// it is a generic
ParameterizedType pType = (ParameterizedType) type;
Type[] actualTypes = pType.getActualTypeArguments();
// and then we have an array, which in this case should be String.class and Object.class, which we can then compare
}
...
}
This is nice, but spring kinda has the problem that those objects *might* be more then they are... they might be AOP'd!
In that case, we do not get the actual objects, but proxies... which, of course, do *not* have the same inheritance tree. To get the actual classes in that case, use the following:
private Class<?> getClass(Object clazzInstance) {
// if it is a (spring) proxy, find the actual type behind it
Class<?> clazz = clazzInstance.getClass();
if(Advised.class.isAssignableFrom(clazz)){
return (Class<>) ((Advised)clazzInstance).getTargetSource().getTargetClass();
}
return clazz;
}
So, here goes.
As can be easily found, it is possible to determine the actual type of a generic class at runtime.
And in the code we get a number of lists<>... and we want to sort them by class hierarchy (so, String extends Object, and thus List<String> should go after List<Object>)
Our compare method then needs to look like this:
compare( List left, List right) {
Type type = left.getClass().getGenericSuperclass()
if(type instanceof ParameterizedType) {// it is a generic
ParameterizedType pType = (ParameterizedType) type;
Type[] actualTypes = pType.getActualTypeArguments();
// and then we have an array, which in this case should be String.class and Object.class, which we can then compare
}
...
}
This is nice, but spring kinda has the problem that those objects *might* be more then they are... they might be AOP'd!
In that case, we do not get the actual objects, but proxies... which, of course, do *not* have the same inheritance tree. To get the actual classes in that case, use the following:
private Class<?> getClass(Object clazzInstance) {
// if it is a (spring) proxy, find the actual type behind it
Class<?> clazz = clazzInstance.getClass();
if(Advised.class.isAssignableFrom(clazz)){
return (Class<>) ((Advised)clazzInstance).getTargetSource().getTargetClass();
}
return clazz;
}
Reacties
Een reactie posten