我需要一个递归函数,它会打印一个类签名,包括类名和值类型参数。
MyNewClass<串,列表与LT;整数>,地图<列表与LT;整数>,字符串>> x = new MyNewClass< ...>(); Assert.assert(getSimpleNameWithGenerics(x).equals(“MyNewClass< String,List< Integer>,Map< List< Integer>,String>>”));
由于我是Java的新手,我很惊讶,不是在Java社区的任何地方找到这样的功能,也不能自己轻松地实现它。
这是我的尝试:
public static String getGenericClassSimpleName(Class<?> c){
String s = c.getSimpleName(); TypeVariable[] tv = c.getTypeParameters(); for(int i = 0; i < tv.length; i++) { s += i == 0 ? "<" : ","; s += getGenericClassSimpleName(tv[i].getGenericDeclaration().getClass()); } if(tv.length > 0) s += ">"; return s;
}
,但最终会出现堆栈溢出(这就是为什么我决定在这里问一下,大声笑),碰到TypeVariable类......我从来没有找到方法来获得类型变量的真实“面孔”。
答案 0 :(得分:0)
您必须拥有一个使用您感兴趣的类型的字段或方法,然后您可以“反思”它并查看所有通用详细信息。
或者你可以从Jackson中的类型捕获技术开始,然后从那里挖掘到支持它的库。
答案 1 :(得分:0)
类可以访问其类型参数,Fields参数和Method参数。我使用这段代码来提取实际的类型参数(它被简化 - “。get ...()[0]”,因为我只需要提取第一个类型参数。)
private Class extractClass(Type type) {
Class result = null;
if (type instanceof Class)
result = (Class) type;
if (type instanceof WildcardType) {
if (((WildcardType) type).getLowerBounds().length > 0) {
result = extractClass(((WildcardType) type).getLowerBounds()[0]);
} else if (((WildcardType) type).getUpperBounds().length > 0) {
result = extractClass(((WildcardType) type).getUpperBounds()[0]);
}
} else if (type instanceof ParameterizedType) {
result = extractClass(((ParameterizedType) type).getActualTypeArguments()[0]);
} else if (type instanceof TypeVariable) {
TypeVariable tv = (TypeVariable) type;
Class c = getEntityClass();
result = extractTypeVariableBounds(tv, c);
if (result == null)
result = extractTypeVariableBounds(tv, (Class) tv.getGenericDeclaration());
if (result == null && tv.getBounds().length > 0)
result = extractClass(tv.getBounds()[0]);
}
return result;
}
private Class extractTypeVariableBounds(TypeVariable tv, Class c) {
if (c == null)
return Object.class;
Type genericSuperclass = c.getGenericSuperclass();
if (genericSuperclass != null) {
int index = 0;
for (TypeVariable dtv : c.getSuperclass().getTypeParameters()) {
if (dtv.equals(tv)) {
while (genericSuperclass instanceof Class) {
genericSuperclass = ((Class) genericSuperclass).getGenericSuperclass();
}
if (genericSuperclass != null)
return extractClass(((ParameterizedType) genericSuperclass).getActualTypeArguments()[index]);
}
index++;
}
c = c.getSuperclass();
return extractTypeVariableBounds(tv, c.getSuperclass());
}
if (tv.getBounds().length > 0)
return extractClass(tv.getBounds()[0]);
return Object.class;
}
请参阅此课程:AEntityAccessor.java和PropertyAccessor.java,了解其如何用于提取地图参数。
这不是一个直接的答案,但我希望你会觉得这很有用。