Search code examples
javareflectionannotationsspringfox

Can I pass a class literal from a templated class as an argument for an annotation?


I have an annotation that takes a Class<?> as value (the response field of @ApiResponse from springfox). The response I want to be mapped is a templated class (PageDTO<T>) but I can not get a class literal for my specific entity, e.g. PageDTO<BusinessClass>.class. The only option that works is defining another class:

class Doc extends PageDTO<BusinessClass> 

and pass the value of Doc.class as a parameter.

Is there a way of achieving the same result without defining a class for each annotated method?

I tried the double casting method:

(Class<PageDto<BusinessClass>>)(Class<?>)PageDTO.class 

but it did not work.


Solution

  • Class does represent single class, PageDTO<BusinessClass> is not a class it is a parametrised generic type of PageDTO class with BusinessClass class parameter. (see java.lang.reflect.ParameterizedType/java.lang.reflect.Type)

    So answer is: it is not possible to do this.

    Biggest issue here is that you want to use annotations, as otherwise you could use similar syntax to TypeToken from GSON library (or just use it), but with annotations you would need to create normal named class for this.

    Do you really need that type? can't you read it from other place? (I'm not familiar with springfox) maybe return type?
    Otherwise you can try to create more advanced annotation with place for both class and optional parameters, but that would also be far from perfect - as you would not be able to handle nested generic types or wildcards.
    Other option would be to use strings to represent generic type, but then it isn't type safe and you would need or write some library to parse that back to java.lang.reflect.Type