getSimpleNameWithGenerics (Class <?> clazz) - PullRequest
       6

getSimpleNameWithGenerics (Class <?> clazz)

0 голосов
/ 16 января 2011

Мне нужна рекурсивная функция, которая печатает сигнатуру класса, включая имя класса и значения параметров типа uf.

MyNewClass , Map , String >> x = new MyNewClass <...> (); Assert.assert (getSimpleNameWithGenerics (x) .equals ("MyNewClass , Map , 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 ... Я никогда не находил способ добраться до реальных "граней" переменных типа.

Ответы [ 2 ]

0 голосов
/ 16 января 2011
Класс

может иметь доступ к параметрам своего типа, параметрам полей и параметрам метода. Я использую этот фрагмент кода для извлечения фактических параметров типа (он упрощен - ". 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 , чтобы узнать, как его использовать для извлечения параметров карты.

это не прямой ответ, но все же, я надеюсь, вы найдете это полезным.

0 голосов
/ 16 января 2011

У вас должно быть поле или метод, который использует интересующий вас тип, а затем вы можете «обдумать» его и увидеть все общие сведения.

Или вы можете начать с технологии захвата типов в Джексон и перейти оттуда к библиотеке, которая ее поддерживает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...