How can I get a parameterized type class from a parameter argument of a parameterized type method?

Consider this contrived class:

import java.util.List;
public class Test {
    public String chooseRandom(List<String> strings) {
        return null;
    }
}

When using reflection to test this method, how can I get an object Classrepresenting java.lang.String(or even a string "java.lang.String") while looking at the arguments for chooseRandom?

I know that Java erases types at compile time, but they should still be there, as it javapcan print them correctly. Execution javapin this compiled class results in:

Compiled from "Test.java"
public class Test {
  public Test();
  public java.lang.String chooseRandom(java.util.List<java.lang.String>);
}

The parameterized type for java.util.List( java.lang.String) is definitely available ... I just can't figure out what it is.

I tried this:

Class clazz = [grab the type of chooseRandom parameter list first argument];
String typeName = clazz.getName();
TypeVariable[] genericTypes = clazz.getTypeParameters();
if(null != genericTypes && 0 < genericTypes.length)
{
    boolean first = true;
    typeName += "<";
    for(TypeVariable type : genericTypes)
    {
        if(first) first = false;
        else typeName += ",";

        typeName += type.getTypeName();
    }

    typeName = typeName + ">";
}

It gives me typeNameof java.util.List<E>. I hope so java.util.List<java.lang.String>.

SO, , , , , ... .

+4
3

getGenericParameterTypes getActualTypeArguments :

Method m = Test.class.getMethod("chooseRandom", List.class);
Type t = m.getGenericParameterTypes()[0];
// we know, in this case, that t is a ParameterizedType
ParameterizedType p = (ParameterizedType) t;
Type s = p.getActualTypeArguments()[0]; // class java.lang.String

, , , , , .

+3

Method.getGenericParameterTypes() ParameterizedType , . Test.class.getMethod("chooseRandom", List.class).getGenericParameterTypes() , ParameterizedType.

0

Java , " " (java.util.List) . Method.getParameterTypes()[i] (String, ). Method.getGenericParameterTypes, java.lang.reflect.Type.

, , , , :

public String getDataType(Class clazz)
{
    if(clazz.isPrimitive())
        return clazz.getName();

    if(clazz.isArray())
        return getDataType(clazz.getComponentType()) + "[]";

    String typeName;
    if("java.lang".equals(clazz.getPackage().getName()))
        typeName = clazz.getName().substring(10);
    else
        typeName = clazz.getName();

    return typeName;
}

public String getDataType(Type type)
{
    if(type instanceof Class)
        return getDataType((Class)type);

    if(type instanceof ParameterizedType)
    {
        ParameterizedType pt = (ParameterizedType)type;
        StringBuilder typeName = new StringBuilder(getDataType(pt.getRawType()));

        Type[] specificTypes = pt.getActualTypeArguments();
        if(null != specificTypes && 0 < specificTypes.length)
        {
            typeName.append("<");
            for(int j=0; j<specificTypes.length; ++j)
            {
                if(j > 0)
                    typeName.append(",");

                typeName.append(getDataType(specificTypes[j]));
            }

            typeName.append(">");
        }

        return typeName.toString();
    }

    return "[" + type + ", a " + type.getClass().getName() + "]";
}

public void getMethodSignature(Method m)
{
    System.out.print(getDataType(m.getGenericReturnType());
    System.out.print(" ");
    System.out.print(method.getName());
    System.out.print("(");
    Type[] parameterTypes = method.getGenericParameterTypes();
    if(null != parameterTypes && 0 < parameterTypes.length)
    {
        for(int i=0; i<parameterTypes.length; ++i)
        {
            if(0<i) System.out.print(",");
            System.out.print(getDataType(parameterTypes[i]));
        }
    }
    System.out.println(")");
}

, , : , ..

, :

protected void parseLocalesHeader(String string,
                                  java.util.TreeMap<Double,java.util.ArrayList<java.util.Locale>> treeMap)

Note that it does not currently handle multiple implementations Type, for example TypeVariable(one that looks like <T extends Serializable>). I will leave this an exercise for anyone who wants to follow in my footsteps. The above code should help you.

0
source

All Articles