Java编译期注解是一种在Java编译时期处理的注解,它通过在源代码上附加注释信息的方式,在Java程序编译期处理中对注解进行分析并进行特定处理,从而可以在程序运行期间实现一些自定义功能。
以下是Java编译期注解的一些使用攻略:
1. 创建注解类
首先,我们需要定义一个注解类。注意,注解类的定义必须加上 @interface,以表示它是一个注解。
@Retention(RetentionPolicy.SOURCE) // 仅在源码中保留
@Target(ElementType.TYPE) // 仅作用在类上
public @interface Generated {
String[] value() default "";
String[] comments() default "";
}
2. 添加注解
添加注解需要使用 @注解名 的方式,将注解添加在需要处理的代码块、类、方法或方法参数上。
@Generated(value = "generated by myutil", comments = "a simple logger")
public class Logger {
// ...
}
3. 处理注解
在编译时期,可以通过编写注解处理器对注解进行处理。下面是一个简单的例子,用来生成一些类似于 lombok 的 getter 和 setter 方法。
@SupportedAnnotationTypes("com.example.Getter")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
public class GetterProcessor extends AbstractProcessor {
private static final boolean SHOULD_GENERATE = true;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement annotation : annotations) {
for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
if (element.getKind() == ElementKind.FIELD) {
generateGetter((VariableElement) element);
generateSetter((VariableElement) element);
}
}
}
return SHOULD_GENERATE;
}
private void generateGetter(VariableElement element) {
// 生成 getter 方法的代码
}
private void generateSetter(VariableElement element) {
// 生成 setter 方法的代码
}
}
上面的代码生成的 getter 和 setter 方法的名字和类型都是固定的,如果需要生成不同的方法,可以在注解中定义相应的参数或属性。
示例一:使用注解生成POJO类的toString方法
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface ToString {
String includeFields() default ""; // 要包含的成员变量的名称,多个用逗号隔开
}
// 在POJO类上加上注解
@ToString(includeFields = "name,age")
public class Person {
private String name;
private int age;
// getter/setter 省略
// 生成 toString 方法
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName() + "{");
String[] fields = includeFields.split(",");
for (String field : fields) {
try {
sb.append(field + "=" + getClass().getDeclaredMethod("get" + StringUtils.capitalize(field)).invoke(this) + ",");
} catch (Exception e) {
// 忽略异常
}
}
sb.deleteCharAt(sb.length() - 1);
sb.append("}");
return sb.toString();
}
}
示例二:使用注解生成SQL语句
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface CreateTable {
String tableName();
}
// 在POJO类上加上注解
@CreateTable(tableName = "person")
public class Person {
private String name;
private int age;
// getter/setter 省略
// 生成 SQL 语句
public static String createTableSQL() {
Class<Person> clazz = Person.class;
CreateTable createTableAnnotation = clazz.getAnnotation(CreateTable.class);
String tableName = createTableAnnotation.tableName();
StringBuilder builder = new StringBuilder();
builder.append("CREATE TABLE " + tableName + "( ");
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
if (fieldName.equals("serialVersionUID")) {
continue;
}
builder.append(fieldName + " " + getColumnType(field.getType()) + ",");
}
builder.deleteCharAt(builder.length() - 1);
builder.append(");");
return builder.toString();
}
private static String getColumnType(Class<?> type) {
if (type == int.class || type == Integer.class) {
return "INTEGER";
} else if (type == long.class || type == Long.class) {
return "BIGINT";
} else if (type == boolean.class || type == Boolean.class) {
return "BOOLEAN";
} else {
return "VARCHAR(255)";
}
}
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:什么是Java编译期注解? - Python技术站