Search code examples
javagenericsreflectiongroovytype-erasure

get property types at runtime


I have a Groovy class such as

class User {
    List<Foo> someFoos = new ArrayList<Foo>()
    List<Bar> someBars = new ArrayList<Bar>()    
}

I can iterate over these properties at runtime using

def user = new User()
List<MetaProperty> setProperties = user.metaClass.properties.findAll {MetaProperty property ->
    property.name.startsWith('some')
}

If I inspect the type of each of these properties Set is returned

setProperties.each {MetaProperty setProperty -> 
    assert setProperty.type == Set    
}

Is there any way at runtime I can get the generic type parameter (Foo and Bar) for each of these properties?

I strongly suspect I cannot due to type erasure, but If someone could confirm my suspicions, I'd appreciate it.


Solution

  • Yes, you can. These are field definitions and they retain their type definitions at runtime. I'll give you the java code, you can also use it in groovy (I don't know a groovy-specific solution)

    Field[] fields = User.class.getDeclaredFields();
    for (Field field : fields) {
        ParameterizedType pt = (ParameterizedType) field.getGenericType();
        Type concreteType = pt.getActualTypeArguments()[0];
    }