这似乎是一个常见的问题,所以对于那些来自谷歌的人来说:有希望。
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;
}
}
Element
在处理器上调用 Dagger 方法为该_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];
}