获取 AnnotationProcessor 中带注释 class 的包名称

Get package name of a annotated class within AnnotationProcessor

我有一个 class,我使用 AnnotationProcessor 对其进行处理。 在此过程中,我有一个 javax.lang.model.element.Element 的实例,我可以在其中获取 .getSimpleName() 注释的 class 的名称。我知道需要的是带注释的 class.

的 packageName (com.software.cool)

知道如何通过 API 接收它吗?

您可以在 class 对象上使用 getPackage() 方法,即

Element target;
Package pkg = target.getClass().getPackage();
String pkgName = pkg.getName();

进一步阅读: getPackage Javadocs

element.getQualifierName()居然有我想要的!

感谢@Yogi

你肯定不想使用getQualifiedName:它在某些情况下会产生令人惊讶的结果。例如,无法区分包名的最后一部分和内部classes的父class:在"java.util.Map.Entry"中是"Map"包名的一部分或名称包含 Entry 的 class?如果 "java.util.Map.Entry" 不是 "a.b.c.d"(Proguard 处理代码的典型案例)怎么办?

同样,对于默认(未命名)包中的 classes,点之前不会有任何内容……

使用 getQualifiedName,您的解析代码将变得复杂且不可靠。一般来说,当您必须使用 Element 的字符串表示时,您就做错了。

这是获取 element:

包的正确模式
Element enclosing = element;
while (enclosing.getKind() != ElementKind.PACKAGE) {
    enclosing = enclosing.getEnclosingElement();
}
PackageElement packageElement = (PackageElement) enclosing;

这将在 所有 情况下正确获取包裹。

最好的方法是 ProcessingEnvironment.getElementUtils(),那里有一个非常方便的方法,叫做 getPackageOf。 为了获得 ProcessingEnviroment,您必须在 AbstractProcessor 实现中覆盖 init 方法。

public class DynamicServiceProcessor extends AbstractProcessor {

private ProcessingEnvironment processingEnvironment;
private Elements elementUtils;

@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
    super.init(processingEnvironment);
    this.processingEnvironment = processingEnvironment;
    this.elementUtils = processingEnvironment.getElementUtils();
}

@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
    ...
    for (Element element : roundEnvironment.getElementsAnnotatedWith(DynamicService.class)) {
        PackageElement packageElement = processingEnvironment.getElementUtils().getPackageOf(element);
    }
    ...