1

Lets say I have some class in Java that implements List<T> called Foo that extends it with String, how can I get the type variable of the List(which is in this example is String)? [Just to know before I go and implement this myself, P.S. I am sure that springframework can do this]

NOTICE that this could be done because Foo class metadata contains the generic super class and interfaces and not the same as wanting to know the type inside new LinkedList<String>()

NOTICE that using ((ParameterizedType)Foo.class.getGenericSuperClass()).getActualTypeArguments()[0] is not good enough for my needs(see the code below: Foo and Bar)

Code that shows what I want:

// java.util: interface List<T> { }

interface TypeList<A, T> extends List<T> { }

interface Foo extends List<String> { }

interface Bar extends TypeList<Integer, Long> { }

Class<?> getTypeParameter(Class<?> fromClass, Class<?> superTypeWithTypeVariables, int indexOfTypeVariable) {
    // ...
}

// Foo -> List<String> -> List<E> -> E is #0
assertEquals(String.class, getTypeParameter(Foo.class, List.class, 0))
// Bar -> TypeList<..., Long> -> TypeList<..., T> -> List<T> -> List<E> -> E is #0
assertEquals(Long.class, getTypeParameter(Bar.class, List.class, 0))

The implementation needs to go over all the class hierarchy and use ParameterizedType and TypeVariable interfaces, and some other staff.

But this question is off-topic because I asked what library implements this(see https://stackoverflow.com/help/on-topic)

Ido Sorozon
  • 272
  • 1
  • 12
  • Library requests are off-topic. – Jorn Vernee May 11 '17 at 18:24
  • @JornVernee: This is not a library request. – SLaks May 11 '17 at 18:25
  • @SLaks This kinda is – Ido Sorozon May 11 '17 at 18:26
  • @JornVernee Can you show me where Thay say that its not allowed? and how do I delete the question? and what should I do? – Ido Sorozon May 11 '17 at 18:28
  • @SLaks is library request a request to tell me about a library? – Ido Sorozon May 11 '17 at 18:30
  • A library request means a request for a library that does something. – SLaks May 11 '17 at 18:35
  • So, this is a library request... – Ido Sorozon May 11 '17 at 18:36
  • anyway I don't think any library can do this with pure java as this cannot be done even with reflection with the definitions of interfaces and classes above, however maybe this can be done with aspect frameworks or bytecode manipulation but I'm not sure – niceman May 11 '17 at 18:42
  • by the way when you have 50+ reputation you can access chat where you can ask about libraries on the respective channel – niceman May 11 '17 at 18:44
  • @niceman This can be done with reflection. The `String` parameter is hard-coded into the class file, and available at runtime. – Jorn Vernee May 11 '17 at 18:46
  • @IdoSorozon Here is a list of things that are off-topic: https://stackoverflow.com/help/on-topic Which includes: _"Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource..."_. – Jorn Vernee May 11 '17 at 18:47
  • We could be a little more flexible with XY problems that explicitly ask for a library, that are really asking "how can I do this?" Edited question to reflect this. – Andy Thomas May 11 '17 at 18:53
  • @AndyThomas, I Know How to do this, I need to iterate over all the class hirarcey using `getGenericSuperClass` and `getGenericSuperInterface` and when the `Type` is `ParameterizedClass` I need to get The `TypeVariable` and match the indexes and the names from the `ParameterizedType` and the `getRawType`, It is a grate hustle and can not be done simply withe the code you linked, see the class `Bar` – Ido Sorozon May 11 '17 at 21:20
  • @AndyThomas please remove the duplicate tag, as It is not a duplicate(I explained in the question) – Ido Sorozon May 11 '17 at 21:30
  • @JornVernee my bad, thanks for clarification – niceman May 12 '17 at 15:27

1 Answers1

0

You can use my utility GenericUtil, see it here.

Use the following method

public static Type[] getGenericTypes(Type sourceType, Class<?> targetClass)

It can infer any generic type even it's not explicit.

In you case you can do

getGenericTypes(Foo.class, List.class) // {String.class}
getGenericTypes(Bar.class, List.class) // {Long.class}
getGenericTypes(Bar.class, TypeList.class) // {Integer.class, Long.class}

Even you can do

interface Baz<T> extends TypeList<T, Long> {}
getGenericTypes(Baz.class, List.class) // {Long.class}
getGenericTypes(Baz.class, TypeList.class) // {T, Long.class}
Dean Xu
  • 4,438
  • 1
  • 17
  • 44