0

I have the following method:

public <T> void meth(T t){

}

Inside method I need to check that t is Collection of String(List<String>, Set<String>, etc)

I understand that I can do it using reflection but I don't know how certainly.

P.S.

I believe that org.springframework.core.GenericTypeResolver#resolveTypeArgument need to resolve this problem but I don't understand which arguments to pass.

I have read this topic https://stackoverflow.com/a/9202329/2674303 but I don't know how to apply it in my situation

Community
  • 1
  • 1
gstackoverflow
  • 36,709
  • 117
  • 359
  • 710

1 Answers1

2

By reflection, you can test that t is a Collection but because of type erasure, you cannot check that it is a Collection<String>.

Here is still how to check that t is a Collection.

public <T> void meth(T t){
  if(Collection.class.isAssignableFrom(t.getClass())) {
    System.out.println(true);
  } else {
    System.out.println(false);
  }

Note that you can still test individual elements of the collection but if you need to do that, you probably have a design problem.

In answer to gstackoverflow's comment:

I checked this link and I needed some time to understand it. The short answer is "You cannot because the generic type is replaced with Object at compile time." (type erasure) but you can still get the information that is available at compile time and it can be enough depending on your use case.

For example :

private static Type[] getTypes(Object object) {
  return ((ParameterizedType)object.getClass().getGenericSuperclass()).getActualTypeArguments();
}

Sometimes, it will be useless :

Map<Integer, String> object = new HashMap<>();
for (Type actualTypeArgument : getTypes(object)) {
  System.out.println(actualTypeArgument);
}

Answer :

K
V

(And indeed, at compile time, you do not have any other information about generic type of Map<K, V>).

But sometimes, it can be useful :

public class IntegerList extends ArrayList<Integer> {
}

for (Type actualTypeArgument : getTypes(new IntegerList())) {
  System.out.println(actualTypeArgument);
}

Answer :

class java.lang.Integer

This one works because at compile time, the compiler knows that IntegerList is a List<Integer>.

In other words, you can access the information that is available at compile-time but not the information which is known at runtime.

Arnaud Denoyelle
  • 29,980
  • 16
  • 92
  • 148