9

I need to check that the type of the method first parameter is List<Class<? extends Exception>> or not. Can anybody suggested better solution than comparing it with a String?

Method m = Foo.class.getMethod("m1", List.class);
if (m.getGenericParameterTypes()[0].toString().equals("java.util.List<java.lang.Class<? extends java.lang.Exception>>")) {
  ...
}

I mean something like this:

List.class.isAssignableFrom((Class<?>)((ParameterizedType)m.getGenericParameterTypes()[0]).getRawType()));

This check that it is a list or not. But how I can check the Class<? extends Exception> part of the type?

4 Answers 4

5

Just tried the following, and it seems to work:

// package whatever.your.package.happens.to.be;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.WildcardType;
import java.util.List;

public class ReflectionTest {
  public static void main(String[] args) throws NoSuchMethodException, SecurityException {
    Method method = ReflectionTest.class.getMethod("method", List.class);
    ParameterizedType listType = (ParameterizedType)method.getGenericParameterTypes()[0];
    ParameterizedType classType = (ParameterizedType)listType.getActualTypeArguments()[0];
    WildcardType genericType = (WildcardType)classType.getActualTypeArguments()[0];
    Class<?> genericClass = (Class<?>)genericType.getUpperBounds()[0];

    boolean isException = Exception.class.isAssignableFrom(genericClass);
    // vvv Prints out "Is Class<? extends Exception>: true"
    System.out.println("Is Class<? extends Exception>: " + isException);

    boolean isRuntimeException = RuntimeException.class.isAssignableFrom(genericClass);
    // vvv Prints out "Is Class<? extends RuntimeException>: false"
    System.out.println("Is Class<? extends RuntimeException>: " + isRuntimeException);
  }

  public void method(List<Class<? extends Exception>> exceptionClasses) {
    // Do something with "exceptionClasses," I would imagine...
  }
}

Edit: Okay, for reals this time. I just now noticed that it was List<Class<? extends Exception>> and not List<? extends Exception>. So this (hopefully) final solution should actually match that case.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, I mean List<Class<? extends Exception>>, not List<Exception> as the method input parameter.
1

EDIT:

Q: How to read the upper bound from parameter argument ?

For example we will use method description

public void testMethod(Collection<? extends Exception);

First we must access to parameter of method parameter

 ParametrizedType parametrizedType = (ParametrizedType)method.getGenericParametersTypes()[0];

From this parametrizedType we must get it argument:

Type argumentOfargument  parametrizedType.getActualTypeArguments()[0];

So far so good, now we need to check that this argumentOfargument is an wildcard.

if(arguemntOfargument instaceof WildcardType) {
   WidlcardType wildcardArgumentofArgumentType = (WidlcardType )argumentOfargument;  
}

At this point we have two options for upper :

  return  wildcardArgumentofArgumentType.getUpperBounds()[0]

or for lower :

  return  wildcardArgumentofArgumentType.getLowerBounds()[0]

3 Comments

I am working with methods at runtime. A mechanism select some methods, and I need to produce the parameters to call the method. That is why I want to identify, is it a List<? extends Exception> parameter or not. I have no parameter instances, I want to create it after the type is exactly identified.
You should add this comment to your question. It really change the context of your goal.
@user1534880, please see EDIT. This should solve your problems.
0

I think that after Type Erasure you can'get that kind of information.

If you don't know about how that works check out the official documentation: Java type erasure

In short when the compiler interprets your code it clears all generic information and replaces them with the bounded parameters or with Object if they are not bound.

You can use the instanceof operator however to check for the Exception type.

Edit: If you want to check a parameter before actually calling the method you can try using the Proxy pattern. Details here: Proxy pattern

3 Comments

Thank you for your answer. I cant use instanceof because the method has not called yet, so I have no instance from the method parameter.
You can create a Proxy object which wraps your Object and you can check for parameters before actually calling the method.
Sorry, but this is wrong. Type erasure applies to dynamic types/objects/instances/method-arguments, not to static types/signatures/method-parameters.
0

Do you need it to be specifically List<Class<? extends Exception>>, or are supertypes (such as Collection<Class<? extends Exception>>, or even Object) O.K.? I ask because you mention isAssignableFrom, which looks for a subtype-supertype relationship.

If you're looking for a subtype-supertype relationship, then you can do something like what Random Human describes.

If you're looking for an exact match, then you should be able to use equals: the various classes and interfaces in the reflection API specify friendly definitions of equals. For example, ParameterizedType says:

Instances of classes that implement this interface must implement an equals() method that equates any two instances that share the same generic type declaration and have equal type parameters.

Of course, this requires having some example somewhere of a List<Class<? extends Exception>> parameter whose type you can obtain and perform the equals comparisons against.

(But to be honest, the toString approach, while hackish, doesn't look that bad to me!)

2 Comments

Hi, Thank you for your answer. I am looking for an exact match. Is it possible to create a specified Type instead of "having some example somewhere... and obtain the type"?
@user1534880: There are no standard JDK classes that implement ParameterizedType, so -- no, not really. I mean, it's an interface, so you could create your own implementation and do all the work yourself, but I don't think it's worth it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.