我尝试了此代码,它返回实际的泛型类型类,因此似乎可以检索类型信息。但是,这仅适用于方法 1 和 2。方法 3 似乎没有像海报假定的那样返回列表类型字符串,因此失败。
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try{
Method m = Main.class.getDeclaredMethod("method1", new Class[]{});
instanceOf(m, List.class, String.class);
m = Main.class.getDeclaredMethod("method2", new Class[]{});
instanceOf(m, List.class, String.class);
m = Main.class.getDeclaredMethod("method3", new Class[]{});
instanceOf(m, List.class, String.class);
m = Main.class.getDeclaredMethod("method4", new Class[]{});
instanceOf(m, StringList.class);
}catch(Exception e){
System.err.println(e.toString());
}
}
public static boolean instanceOf (
Method m,
Class<?> returnedBaseClass,
Class<?> ... genericParameters) {
System.out.println("Testing method: " + m.getDeclaringClass().getName()+"."+ m.getName());
boolean instanceOf = false;
instanceOf = returnedBaseClass.isAssignableFrom(m.getReturnType());
System.out.println("\tReturn type test succesfull: " + instanceOf + " (expected '"+returnedBaseClass.getName()+"' found '"+m.getReturnType().getName()+"')");
System.out.print("\tNumber of generic parameters matches: ");
Type t = m.getGenericReturnType();
if(t instanceof ParameterizedType){
ParameterizedType pt = (ParameterizedType)t;
Type[] actualGenericParameters = pt.getActualTypeArguments();
instanceOf = instanceOf
&& actualGenericParameters.length == genericParameters.length;
System.out.println("" + instanceOf + " (expected "+ genericParameters.length +", found " + actualGenericParameters.length+")");
for (int i = 0; instanceOf && i < genericParameters.length; i++) {
if (actualGenericParameters[i] instanceof Class) {
instanceOf = instanceOf
&& genericParameters[i].isAssignableFrom(
(Class) actualGenericParameters[i]);
System.out.println("\tGeneric parameter no. " + (i+1) + " matches: " + instanceOf + " (expected '"+genericParameters[i].getName()+"' found '"+((Class) actualGenericParameters[i]).getName()+"')");
} else {
instanceOf = false;
System.out.println("\tFailure generic parameter is not a class");
}
}
} else {
System.out.println("" + true + " 0 parameters");
}
return instanceOf;
}
public List<String> method1() {
return null;
}
public ArrayList<String> method2() {
return new ArrayList<String>();
}
public StringList method3() {
return null;
}
public <T extends StringList> T method4() {
return null;
}
此输出:
Testing method: javaapplication2.Main.method1
Return type test succesfull: true (expected 'java.util.List' found 'java.util.List')
Number of generic parameters matches: true (expected 1, found 1)
Generic parameter no. 1 matches: true (expected 'java.lang.String' found 'java.lang.String')
Testing method: javaapplication2.Main.method2
Return type test succesfull: true (expected 'java.util.List' found 'java.util.ArrayList')
Number of generic parameters matches: true (expected 1, found 1)
Generic parameter no. 1 matches: true (expected 'java.lang.String' found 'java.lang.String')
Testing method: javaapplication2.Main.method3
Return type test succesfull: false (expected 'java.util.List' found 'com.sun.org.apache.xerces.internal.xs.StringList')
Number of generic parameters matches: true 0 parameters
Testing method: javaapplication2.Main.method4
Return type test succesfull: true (expected 'com.sun.org.apache.xerces.internal.xs.StringList' found 'com.sun.org.apache.xerces.internal.xs.StringList')
Number of generic parameters matches: true 0 parameters