首页 > 解决方案 > 编译时注释处理

问题描述

有没有办法在 Java 中进行编译时注释处理?

考虑这个例子:

@Name("appName")
private Field<String> appName;

public void setAppName(String name) {
   appName.setValue(name);
}

public String getAppName(String name) {
   return appName.getValue();
}

public void someFunction() {
   String whatFieldName = appName.getName();
}

注释Name将在编译时处理以设置值的地方Field是没有常见的运行时注释处理。因此,当appName.getName();( Field) 被访问时,它将返回类型化的值。

标签: java

解决方案


Yes, there is, but, no, it cannot change existing files. You can 'plug in' to the compiler and be informed of any annotations; as part of this, you can see signatures (so, field declarations, method signatures, types, etc) but no contents (so not the expression used to initialize a field, and not the contents in the {} of a method declaration), and you can make NEW files, even java files, but you can't edit existing ones.

Project Lombok does edit them, but that is quite the framework to make that possible.

There are some crazy tricks you can use. Project lombok uses one trick (reflect its way into compiler internals, fix everything from there, install agents and plugins in IDEs). Another trick is to use a java source file as a template, of sorts. You name your class some funky (so if you want, say, public class AppDescriptor, you'd actually make the java file AppDescriptorTemplate.java and put public class AppDescriptorTemplate inside. This file has the annotation precisely as you pasted. Your annotation processor can then, during compilation, generate AppDescriptor.java, writing the impls of all methods as simple pass-throughs (a field of type AppDescriptorTemplate is generated, and all methods in ADT are copied over, and the implementations are all one-liners that just invoke that method on the template class). The template class can be package private. In this specific scenario it sounds like you can generate virtually the whole thing based off of pretty much only "appName", though.

Lombok plugs straight into the build and is therefore virtually entirely transparent, in the sense that you simply type in your IDE and the methods it generates just appear as you type, whereas 'normal' annotation processors that e.g. use the XTemplate trick do not work that way and require the build system to kick in, every time. It can be a bit of a productivity drain.


推荐阅读