java - 我可以在不将类名硬编码为字符串文字的情况下将类名作为编译时常量获取吗?

标签 java reflection constants compile-time-constant

我正在研究注释处理器。此代码编译:

package sand;

import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.TypeElement;

@SupportedAnnotationTypes("sand.Foo")
public class FooProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        return false; // TODO
    }
}

但是,我对字符串常量“sand.Foo”感到不满意(在这种情况下不是太多,但在未来更普遍)。

如果 Foo 被重命名或移动到另一个包,这段代码仍然可以编译,但它不会工作。

我想做这样的事情:

@SupportedAnnotationTypes(Foo.class)

那样的话,如果 Foo 的名字改变了,编译就会失败,必须有人来更正文件。

但这不起作用,因为 Class 不是 String。所以我尝试了:

@SupportedAnnotationTypes(Foo.class.getName())

但是编译器不认为这是一个常量表达式,而在这种情况下这是必需的,所以这也不起作用。

有什么方法可以在编译时将类文字强制转换为它的名称吗?

最佳答案

您的处理器可以实现 getSupportedAnnotationTypes() 而不是使用注释在运行时提供支持的注释类型名称:

Set<String> getSupportedAnnotationTypes() {
    Set<String> supportedAnnotationTypes = new HashSet<>();
    supportedAnnotationTypes.add(Foo.class.getName());
    return supportedAnnotationTypes;
} 



如果您想为此继续使用(非标准)注解,您可以创建自己的注解,将编译时类型作为参数,如@k_g 建议的那样。 @SupportedAnnotationTypes没什么特别的,它仅在扩展 AbstractProcessor 时自动使用反正。看看 source code of AbstractProcessor.getSupportedAnnotationTypes() .

自定义注解的签名应该使用Class<?>[]而不是 String[] :

@Target(TYPE)
@Retention(RUNTIME)
public @interface SupportedAnnotationTypes {
    Class<?>[] value();
}

覆盖 getSupportedAnnotationTypes并以与 AbstractProcessor 相同的方式查找您的自定义注释.例如像这样:

public Set<String> getSupportedAnnotationTypes() {
    Class<?>[] types = getClass().getAnnotation(SupportedAnnotationTypes.class).value();
    return Arrays.stream(types).map(Class::getName).collect(Collectors.toSet());
}

关于java - 我可以在不将类名硬编码为字符串文字的情况下将类名作为编译时常量获取吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27955169/

相关文章:

java - 如何在web层捕获OptimisticLockException

java - 在Java中计算闰年

tsql - T-SQL 对参数的反射

java - 如何在 Java 代码中使用 Scala 注解

java - 单元测试时未找到自定义注释

Java:字符串:是否有更好的方法来比较字符串

java - 在 Eclipse 中调试时查找类的所有实例

c++ - 如何允许临时对象使用非常量复制构造函数

c - 当我们打印其他未初始化的变量时, union 如何工作?

c++ - 如何使用 const InputIterators 为通用容器编写函数?