- 看看注解什么样?
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
- 注解到底是什么?
- 是一个类
- 是一种标记,使用@interface标识
- 使用@xxx的形式标注其他类,java注解是附加在代码(注解)中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能,用来描述类或属性
- 注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用
- JDK中的注解及相关讲解
注解分为三类:
- 元注解
- 定义在java.lang.annotation包中,对其他注解进行注解
- @Documented 标记生成javadoc
- @Retention 注解的生命周期,使用枚举类RetentionPolicy标识
- @Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
- @Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
- @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
- @Target 注解的目标
- 如@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
- @Inherited 注解的继承关系
- 标准注解
- @Override 标识为覆写超类方法
- @Deprecated 标识为弃用的类/方法
- @SuppressWarnings 标识抑制编译器发出特定警告
- 一般注解
- @Component
- @Service
- 自定义注解
package com.abuge.demo00001;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* 自定义注解,用于描述字段、方法信息
*
*/
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在且在运行时可以通过反射获取到
@Target({ ElementType.FIELD, ElementType.METHOD }) // 定义注解的作用目标及作用范围为声明的属性(包括枚举常量)、方法
@Documented // 该注解被包含在javadoc中
public @interface FieldMeta {
boolean id() default false; //是否为序列号
String name() default ""; //字段名称
boolean editable() default true; //是否可编辑
boolean summary() default true; //是否在列表中显示
String description() default ""; //字段描述
int order() default 0; //排序字段
}
package com.abuge.demo00001;
/**
* 使用注解
*
*/
public class Anno {
@FieldMeta(id = true, name = "序列号", order = 1)
private int id;
@FieldMeta(name = "姓名", order = 3)
private String name;
@FieldMeta(name = "年龄", order = 2)
private int age;
@FieldMeta(description = "描述", order = 4)
public String desc() {
return "java反射获取方法的注解测试";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.abuge.demo00001;
/**
*
* 字段/方法注解业务类
*
*/
public class SortableField {
private FieldMeta meta;
private String name;
private Class<?> type;
public SortableField() {
}
public SortableField(FieldMeta meta, String name, Class<?> type) {
super();
this.meta = meta;
this.name = name;
this.type = type;
}
public FieldMeta getMeta() {
return meta;
}
public String getName() {
return name;
}
public Class<?> getType() {
return type;
}
public void setMeta(FieldMeta meta) {
this.meta = meta;
}
public void setName(String name) {
this.name = name;
}
public void setType(Class<?> type) {
this.type = type;
}
}
package com.abuge.demo00001;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
*
* 注解信息获取基类
*
*/
public class Parent<T> {
Class<T> entity;
@SuppressWarnings("unchecked")
public List<SortableField> init() {
List<SortableField> fieldList = new ArrayList<SortableField>();
// 获得超类的泛型参数的实际类型
entity = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
if (null != entity) {
Field[] fields = entity.getDeclaredFields();
for (Field field : fields) {
FieldMeta meta = field.getAnnotation(FieldMeta.class);
if (null != meta) {
SortableField sortableField = new SortableField(meta, field.getName(), field.getType());
fieldList.add(sortableField);
}
}
Method[] methods = entity.getDeclaredMethods();
for (Method method : methods) {
FieldMeta meta = method.getAnnotation(FieldMeta.class);
if (null != meta) {
SortableField sortableField = new SortableField(meta, method.getName(), method.getReturnType());
fieldList.add(sortableField);
}
}
Collections.sort(fieldList, new Comparator<SortableField>() {
@Override
public int compare(SortableField o1, SortableField o2) {
return o1.getMeta().order() - o2.getMeta().order();
}
});
}
return fieldList;
}
}
package com.abuge.demo00001;
public class Child extends Parent<Anno> {
}
package com.abuge.demo00001;
import java.util.List;
/**
* 测试类
* @author huxianyang
*
*/
public class AnnotaionTest {
public static void main(String[] args) {
Parent<?> child = new Child();
List<SortableField> fields = child.init();
for (SortableField f : fields) {
System.out.println("字段名称:" + f.getName() + "\t字段类型:" + f.getType() + "\t\t注解名称:" + f.getMeta().name()
+ "\t注解描述:" + f.getMeta().description());
}
}
}