2

I have a problem to solve :) Let's say that I have such structure:

Interfaces:

public interface RestServiceConverter<S, D> {
    public D convert(S input);
}

 

public interface AdvancedRestServiceConverter<D, F, S> extends RestServiceConverter<S, D> {
}

Classes:

public class TestConverter extends SecondAbstractLevel<Integer> {
  @Override
  public ConvertedResult<String> convert(RawResult input) {
    return null;
  }
}

 

public abstract class AbstractTestConverter<S, D> extends SecondAbstractLevel {
}

 

public abstract class SecondAbstractLevel<T>
implements AdvancedRestServiceConverter<ConvertedResult<String>, Integer, RawResult> {
}

Question: is there any simple way to find what types are parameters from RestServiceConverter (look that params are not explicite in this interface but in AdvancedRestServiceConverter in reverse order) starting from TestConverter? Maybe some library can help mi with that. I'm building some functionality in my code, where I have to check if field in some class is same as the second parameter.

Let say I need method like this

findParameter(TestConverter.class, RestServiceConverter.class)

which returns array

[RawType, ConvertedResult<String>]

Thanks for help.

javovy
  • 151
  • 1
  • 1
  • 6
  • This sounds like a disguised version of http://stackoverflow.com/questions/3403909/get-generic-type-of-class-at-runtime (and all the "Linked" questions of this) – Marco13 Oct 09 '16 at 01:16
  • It has nothing to do with http://stackoverflow.com/questions/3403909/get-generic-type-of-class-at-runtime. I'm asking about object graph traversing and library no, how to get type of parameter at runtime. – javovy Oct 10 '16 at 11:35
  • @javovy Actually, you very much are asking about runtime generic info, and the linked thread does have the answer. But... it's rather complex to deal with this yourself. See my answer for an easier solution. – kaqqao Oct 11 '16 at 16:19

3 Answers3

0

Unfortunately not. Java has this rather unfortunate thing known as "type erasure", which means that in your bytecode, RestServiceConverter<S, D> just becomes RestServiceConverter for any S and D you put there.

How a lot of third-party libraries will get around this is to have the implementation take whatever Class<?> instances it needs in order to do its job.

Joe C
  • 15,324
  • 8
  • 38
  • 50
  • Not necessarily true. Generic type information is actually preserved in many cases. E.g. generic information coming form the supertype (exactly the case described here) is preserved. See my answer for details. – kaqqao Oct 11 '16 at 16:12
0

Actually, in your specific case, this should be possible (if I got you right). You have supertypes that will preserve the generic information, so erasure won't bother you.

Library called GenTyRef, and my AnnotatedType-enabled fork GeAnTyRef (both available in Maven Central), can easily get you what you need:

ParameterizedType exact = (ParameterizedType) GenericTypeReflector.getExactSuperType(TestConverter.class, RestServiceConverter.class);
Type[] typeParams = exact.getActualTypeArguments(); //returning exactly what you asked for
kaqqao
  • 12,984
  • 10
  • 64
  • 118
0

Shamelessly linking to my answer on a similar question. Since you have your generic, say E, at hand, you can cast object.getClass() to Class<E>, which sould give you the requested types.

Isabaellchen
  • 98
  • 10