简体   繁体   中英

How to use Java reflection to check if ParameterizedType argument extends a specific class

If I have an interface and class that I cannot change that look something like this:

public interface ISport<PlayerType extends IPlayer> {
       String getName();
       List<PlayerType> getPlayers();
}

public class TeamSport<PlayerType extends IPlayer> implements ISport<PlayerType>{  

    // constructor and a bunch of other methods

    @Override
    String getName(){
         return this.name;
    }

    @Override
    List<PlayerType> getPlayers(){
          // returns a maintained players list
    }
}

I am building a set of attributes for an object of any type, using reflection and the getter methods of the object. I need it to perform nesting, though, where it can identify attributes of attributes.

The following method is a simplification of the attribute extraction method (here it just prints the attributes, where in my real code I'm actually doing something with them). There is also a method isGetter, not shown here, which tests that the method name begins with "get" and the method has no arguments and is not a void method.

But I need it to be able to recognize that the return type of getPlayers() is a list of IPlayers, so I can get the attributes of IPlayers.

public static printAttributes(Class sourceClass){
       for(Method method : sourceClass.getMethods()){
           if(isGetter(method)){
               System.out.println(method.getName());
               if(method.getGenericReturnType() instanceof ParameterizedType){
                    for(Type parameterType : type.getActualTypeArguments()){
                         System.out.println("   Child type: "+parameterType;
                         if(parameterType instanceof Class){
                              printAttributes((Class)parameterType));
                         }
                    }
               }
           }
       }
}

Calling this on an instance of TeamSport yields the following:

getName
getPlayers
   Child type: PlayerType

It does not print any IPlayer attributes.

How do I get those IPlayer attributes in my printAttributes method? Can I somehow get IPlayer from the ParameterizedType? Or just check if any ParamaterizedType's arguments extend IPlayer (which is less ideal, but better than what I've got)?

Java generics erase generic type information on compile. You won't be able to get this information at runtime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM