如何在代码生成的注释处理期间检索注释的类类型?

发布于 2024-12-04 03:57:07 字数 711 浏览 0 评论 0原文

注释处理器将为您提供两个 TypeElement ,一个用于注释对象,一个用于注释本身。

假设在注释处理过程中需要知道注释对象的 Class 类型才能生成代码。可以使用 TypeElement.getQualifiedName()。但是,任何使用 Class.forName(filledQualifiedName) 的尝试都会引发 ClassNotFoundException

这可能意味着该类不在注释处理代码的路径上。是否可以在注释处理期间检索这样的类,而不必将所有注释代码放入处理库的类路径中?

解决方法是生成类似以下内容:

Class c = Class.forName("thefullyqualifiedname");

并在生成的代码中使用 c 代替,但它不干净。

An annotation processor will provide you with two TypeElement, one for the annotated object and one the annotation itself.

Let's assume one needs to know the Class type of the annotated object during annotation processing to generate code. One can extract the qualified name with TypeElement.getQualifiedName(). However, any attempt to use Class.forName(fullyQualifiedName) throws a ClassNotFoundException.

It probably means the class is not on the path of the annotation processing code. Is it ever possible to retrieve such a class during annotation processing without having to put all annotated code in the classpath of the processing library?

A workaround is to generate something like:

Class c = Class.forName("thefullyqualifiedname");

and use c in the generated code instead, but it is not clean.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空心空情空意 2024-12-11 03:57:07

当注释处理发生时,注释类的“Class”对象不可用,这似乎很正常,因为它发生在编译时。这就是 TypeElements 和 TypeMirrors 存在的原因,它们是 Class 对象的严格等效项。

正如您所指出的,注释只能访问其类路径上的类对象。带注释的类不是这种情况,因为它正在编译。

我知道您认为使用字符串限定名称而不是 Class 是不干净的,您是对的。事实上,你应该使用 TypeElement &类型镜子;-) 。

您出于什么原因需要 Class 对象?我很确定你可以用 TypeElement & 做任何事情。类型镜子。

It seems quite normal that the "Class" object of an annotated class is not available when annotation processing occurs, because it happens at compile time. That's why TypeElements and TypeMirrors are there, they are the strict equivalent of the Class object.

As you pointed out, an annotation can only access class objects that are on its classpath. And it's not the case of the annotated class, since it's being compiled.

I understand that you think using string qualified names instead of Class is not clean, and you are right. In fact, you should use TypeElement & TypeMirror ;-) .

For what reason do you need a Class object ? I'm quite sure you can do anything with TypeElement & TypeMirror.

金橙橙 2024-12-11 03:57:07

我能想到的最佳解决方法如下:

    JClass annotatedType = jcmSource.ref(Class.class);

    JInvocation m =  annotatedType.staticInvoke("forName");
    m.arg(fa.getAnnotated().toString());

    JFieldVar field = sourceClass.field(
            JMod.PRIVATE | JMod.STATIC, annotatedType, "c");

    JBlock staticInit = sourceClass.init();

    JTryBlock tb = staticInit._try();
    JBlock jbtb = tb.body();
        jbtb.assign(field, m);
    tb._catch(jcmSource.ref(ClassNotFoundException.class));

它产生:

private static Class c;

static {
    try {
        c = Class.forName("net.codegentest.CodeGenTest");
    } catch (ClassNotFoundException _x) {
    }
}

它不会显式访问带注释的类的类类型,但至少可以在代码中生成它。

The best workaround I could come up with is the following:

    JClass annotatedType = jcmSource.ref(Class.class);

    JInvocation m =  annotatedType.staticInvoke("forName");
    m.arg(fa.getAnnotated().toString());

    JFieldVar field = sourceClass.field(
            JMod.PRIVATE | JMod.STATIC, annotatedType, "c");

    JBlock staticInit = sourceClass.init();

    JTryBlock tb = staticInit._try();
    JBlock jbtb = tb.body();
        jbtb.assign(field, m);
    tb._catch(jcmSource.ref(ClassNotFoundException.class));

which produces:

private static Class c;

static {
    try {
        c = Class.forName("net.codegentest.CodeGenTest");
    } catch (ClassNotFoundException _x) {
    }
}

It does not give explicit access to the class type of the annotated class, but at least, it can be generated in the code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文