统一使用javax.lang.model.type.TypeMirror和java.lang.Class

Unified use of javax.lang.model.type.TypeMirror and java.lang.Class

我有一个接口,其中包含接受类型为 java.lang.Class

的对象的方法
public interface TypeReviewer {
    public int evaluate(Class<?> type);

    ...
}

现在我想支持在注释处理器中使用此接口的对象。 但是,由于有些classes在注解处理的时候可能还没有被编译,看来我需要添加一个方法

    public int evaluate(TypeMirror type)

进入界面。 (我可能还需要添加类型为 javax.lang.model.util.Types 的参数,但这对接下来的问题并不重要)

对我来说,将此方法添加到接口没有任何意义,因为它应该为 javax.lang.model.type.TypeMirror 计算完全相同的值,并且 TypeMirror 基本上代表 Class。 这也是一个可能的失败点,因为在 class 中实现此接口的程序员可能会在完全相同的类型的这些方法中产生不同的结果。

这引出了我的问题: 我可以做些什么来避免这种注释处理和任何其他元编程领域的冗余实现?

在运行时您将无法访问 TypeMirror 实例。在编译时,您将无法访问所有 Class 个实例。因此没有单一的统一选项。我能想到的最佳解决方案(根据您的应用程序的复杂性,这可能是合适的)是构建您自己的简化类型 API。这是一个粗略的草图:

public interface MyType {

    public boolean isSubclassOf(MyType otherType);

}

public class MyTypeClassImpl implements MyType {

    private Class<?> clazz;

    public MyTypeClassImpl(Class<?> clazz) {
        this.clazz = clazz;
    }

    public boolean isSubclassOf(MyType otherType) {
        if(otherType instanceof MyTypeClassImpl) {
            return clazz.isAssignableFrom(((MyTypeClassImpl)otherType).clazz);
        } else {
            throw new RuntimeException("TypeMirror encountered in non-annotation-processing environment");
        }
    }

}

//Similar implementation for type mirrors

public interface TypeFactory {

    public MyType fromJavaType(Object type);

}

public class AnnotationProcessorTypeFactory {

    private ProcessingEnvironment processingEnv;

    public MyType fromJavaType(Object type) {
        if(type instanceof TypeMirror) {
            return MyTypeMirrorImpl((TypeMirror)type);
        } else if (type instanceof Class<?>) {
            return MyTypeMirrorImpl(convertToTypeMirror((Class<?>)type));
        }
    }

    private TypeMirror convertToTypeMirror(Class<?> clazz) {
        return processingEnv.getElementUtils().getTypeElement(clazz.getCanonincalName());
    }

}

public class RuntimeTypeFactory implements TypeFactory {

    public MyType fromJavaType(Object type) {
        if(!(type instanceof Class<?>)) {
            throw new RuntimeException("Illegal use of non-class type in runtime environment");
        }
        return new MyTypeClassImpl((Class<?>)type);
    }

}

目前没有提供统一的蛾模型抽象。

Joe Darcy 的 was/is JEP 119 ("javax.lang.model Implementation Backed by Core Reflection") which unfortunately has not been included into the JDK yet. This blog post 对此进行了一些阐述,OpenJDK 存储库中的某处也曾经有一个原型实现,但我再也找不到了。