我有一个工作注释处理器,可以收集带注释的类的信息。编译期间一切都在那里。但是我想在运行时访问这些结果。
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@AutoService(Processor.class)
public class TestProcessor extends AbstractProcessor {
private final static List<TestInfo> tests = new ArrayList<>();
@Override
public Set getSupportedAnnotationTypes() {
return new LinkedHashSet() {
{
add(Annotation.class.getCanonicalName());
}
};
}
@Override
public boolean process(final Set<? extends TypeElement> annotations,
final RoundEnvironment env) {
System.out.println("Processing!");
if (!env.processingOver()) {
Set<? extends Element> rootE = env.getRootElements();
for (Element e : rootE) {
if (e.getKind() == ElementKind.CLASS) {
TestInfo t = new TestInfo(e.asType().toString());
for (Element se : e.getEnclosedElements()) {
if (se.getKind() == ElementKind.METHOD) {
t.addMethod(se.getSimpleName().toString());
}
}
getTests().add(t);
}
}
getTests().forEach(ti -> {
System.out.println(ti);
});
}
return false;
}
public static TypeElement findEnclosingTypeElement(Element e) {
while (e != null && !(e instanceof TypeElement)) {
e = e.getEnclosingElement();
}
return TypeElement.class.cast(e);
}
/**
* @return the tests
*/
public static List<TestInfo> getTests() {
return tests;
}
}
有没有办法在运行时检索结果? TestProcessor.getTests返回一个空列表。
这是TestInfo类fyi:
public class TestInfo {
private final String name;
private final List<String> methods = new ArrayList<>();
public TestInfo(String name) {
this.name = name;
}
public void addMethod(String m) {
getMethods().add(m);
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @return the methods
*/
public List<String> getMethods() {
return methods;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(name).append(methods.toString());
return sb.toString();
}
}
更新:注释标记为保留运行时。
答案 0 :(得分:1)
注释处理在编译时。因此,您无法在运行时获取信息。
直接的方法是在编译时将信息写为资源文件,并在运行时读取它。
以下是我的例子:
注释:
@Retention(SOURCE)
@Target(TYPE)
public @interface Anno {
}
处理器:
@Override
public boolean processActual(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (roundEnv.processingOver()) {
return false;
}
try {
write(roundEnv);
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
private void write(RoundEnvironment roundEnv) throws IOException, UnsupportedEncodingException {
Filer filer = processingEnv.getFiler();
FileObject resource = filer.createResource(StandardLocation.CLASS_OUTPUT, "", "TestInfo");
OutputStream output = resource.openOutputStream();
PrintStream writer = new PrintStream(output, false, "UTF-8");
roundEnv.getElementsAnnotatedWith(Anno.class)
.stream()
.filter(e -> e.getKind() == ElementKind.CLASS)
.map(e -> e.asType().toString())
.forEach(writer::println);
writer.flush();
}
用户代码:
@Anno
public class Q48177784 {
public static final List<Class<?>> CLASSES;
static {
try {
URL resource = Q48177784.class.getClassLoader().getResource("TestInfo");
CLASSES = Files.readAllLines(Paths.get(resource.toURI()))
.stream()
.map(s -> {
try {
return Class.forName(s);
} catch (ClassNotFoundException e) {
throw new Error(e);
}
})
.collect(Collectors.toList());
} catch (Exception e) {
throw new Error(e);
}
}
public static void main(String[] args) {
System.out.println(CLASSES);
}
}
使用处理器构建后,运行main
方法:
[class xdean.stackoverflow.Q48177784]
对于您的情况,您应该做的唯一事情是序列化/反序列化您的TestInfo
答案 1 :(得分:0)
结帐RUNTIME
。我想你想把它设置为String link = "https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=video&cd=1&cad=rja&uact=8&ved=0ahUKEwjNz9zuhczYAhWJoqQKHbGPDLMQFgglMAA&url=https%3A%2F%2Fwww.youtube.com%2Fchannel%2FUC-9-kyTW8ZkZNDHQJ6FgpwQ&usg=AOvVaw3k7TglV_ogkm4gsxKGAESI";
HttpURLConnection connection = (HttpURLConnection) (new URL(link).openConnection());
connection.connect();
。