Копирование-вставка моего оригинального ответа :
Это, кажется, распространенный вопрос, поэтому для тех, кто прибывает из Google: есть надежда.
The Dagger Проект DI лицензирован по лицензии Apache 2.0 и содержит некоторые служебные методы для работы с типами в процессоре аннотаций.
В частности, класс Util
можно полностью просмотреть на GitHub( Util.java ) и определяет метод public static String typeToString(TypeMirror type)
.Он использует TypeVisitor и некоторые рекурсивные вызовы для создания строкового представления типа.Вот фрагмент для справки:
public static void typeToString(final TypeMirror type, final StringBuilder result, final char innerClassSeparator)
{
type.accept(new SimpleTypeVisitor6<Void, Void>()
{
@Override
public Void visitDeclared(DeclaredType declaredType, Void v)
{
TypeElement typeElement = (TypeElement) declaredType.asElement();
rawTypeToString(result, typeElement, innerClassSeparator);
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
if (!typeArguments.isEmpty())
{
result.append("<");
for (int i = 0; i < typeArguments.size(); i++)
{
if (i != 0)
{
result.append(", ");
}
// NOTE: Recursively resolve the types
typeToString(typeArguments.get(i), result, innerClassSeparator);
}
result.append(">");
}
return null;
}
@Override
public Void visitPrimitive(PrimitiveType primitiveType, Void v) { ... }
@Override
public Void visitArray(ArrayType arrayType, Void v) { ... }
@Override
public Void visitTypeVariable(TypeVariable typeVariable, Void v)
{
result.append(typeVariable.asElement().getSimpleName());
return null;
}
@Override
public Void visitError(ErrorType errorType, Void v) { ... }
@Override
protected Void defaultAction(TypeMirror typeMirror, Void v) { ... }
}, null);
}
Я занят своим собственным проектом, который генерирует расширения классов.Метод Dagger работает для сложных ситуаций, включая общие внутренние классы.У меня есть следующие результаты:
Мой тестовый класс с полем для расширения:
public class AnnotationTest
{
...
public static class A
{
@MyAnnotation
private Set<B<Integer>> _bs;
}
public static class B<T>
{
private T _value;
}
}
Вызов метода Dagger на Element
, который процессор предоставляет для поля _bs
:
accessor.type = DaggerUtils.typeToString(element.asType());
Сгенерированный источник (пользовательский, конечно).Обратите внимание на удивительные вложенные универсальные типы.
public java.util.Set<AnnotationTest.B<java.lang.Integer>> AnnotationTest.A.getBsGenerated()
{
return this._bs;
}
РЕДАКТИРОВАТЬ: адаптировать концепцию для извлечения TypeMirror из первого универсального аргумента, в противном случае NULL:
public static TypeMirror getGenericType(final TypeMirror type)
{
final TypeMirror[] result = { null };
type.accept(new SimpleTypeVisitor6<Void, Void>()
{
@Override
public Void visitDeclared(DeclaredType declaredType, Void v)
{
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
if (!typeArguments.isEmpty())
{
result[0] = typeArguments.get(0);
}
return null;
}
@Override
public Void visitPrimitive(PrimitiveType primitiveType, Void v)
{
return null;
}
@Override
public Void visitArray(ArrayType arrayType, Void v)
{
return null;
}
@Override
public Void visitTypeVariable(TypeVariable typeVariable, Void v)
{
return null;
}
@Override
public Void visitError(ErrorType errorType, Void v)
{
return null;
}
@Override
protected Void defaultAction(TypeMirror typeMirror, Void v)
{
throw new UnsupportedOperationException();
}
}, null);
return result[0];
}