实现自定义注解(代码篇)

这是根据一篇博客写的,原文链接为:https://blog.csdn.net/wangpengzhi19891223/article/details/78131137/#commentBox

我们来逐个讲述编写自定义Annotations的要点。
J2SE5.0版本在 java.lang.annotation提供了四种元注解,专门注解其他的注解:
@Documented –注解是否将包含在JavaDoc中
@Retention –什么时候使用该注解
@Target? –注解用于什么地方
@Inherited – 是否允许子类继承该注解

@Documented–一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。
@Retention– 定义该注解的生命周期。
RetentionPolicy.SOURCE – 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
RetentionPolicy.CLASS – 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
RetentionPolicy.RUNTIME– 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
@Target – 表示该注解用于什么地方。如果不明确指出,该注解可以放在任何地方。以下是一些可用的参数。需要说明的是:属性的注解是兼容的,如果你想给7个属性都添加注解,仅仅排除一个属性
,那么你需要在定义target包含所有的属性。
ElementType.TYPE:用于描述类、接口或enum声明
ElementType.FIELD:用于描述实例变量
ElementType.METHOD
ElementType.PARAMETER
ElementType.CONSTRUCTOR
ElementType.LOCAL_VARIABLE
ElementType.ANNOTATION_TYPE 另一个注释
ElementType.PACKAGE 用于记录java文件的package信息
@Inherited – 定义该注释和子类的关系

注解处理的基础知识

方法1: T getAnnotation(Class annotationClass): 返回改程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。
方法2:Annotation[] getAnnotations():返回该程序元素上存在的所有注解。
方法3:boolean is AnnotationPresent(Class annotationClass):判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
方法4:Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

以下实现自定义注解:

第一:定义三个自定义的注解类

第二:创建一个实体

第三:创建一个中间类

第四:测试

第一步的代码:创建三个自定义注解类

@Retention(RetentionPolicy.RUNTIME)
public @interface CarNameTarger {
	String name() default "";
}

@Retention(RetentionPolicy.RUNTIME)
public @interface CarTypeTarger {
	public String carType();
	public static class Type{
		public static final String benchi = "benchi"; 
	}
}
@Retention(RetentionPolicy.RUNTIME)
public @interface CarSalerTarger {
	public String salername();
	public int age() default 1;
}

第二步代码:创建一个实体类,里面只含有三个字段。

/**
 * @author chenxihua
 * @Date 2018年9月14日
 */
public class BenCar {
	
	@CarNameTarger(name="奔驰车")
	private String name;
	
	@CarTypeTarger(carType = CarTypeTarger.Type.benchi)
	private String type;
	
	@CarSalerTarger(salername="小华",age=24)
	private String carInfo;

}

第三步代码:创建一个中间类,方便测试

/**
 * @author chenxihua
 * @Date 2018年9月14日
 */
public class CarInfoUtil {
	
	public static void getFruitInfo(Class clazz){
        Field[] fields = clazz.getDeclaredFields();
        for(Field field :fields){
            if(field.isAnnotationPresent(CarNameTarger.class)){
                CarNameTarger name = (CarNameTarger) field.getAnnotation(CarNameTarger.class);
                
                // 下面被注释的输出语句是判断上面语句获取值的情况,可知道,上式是获取字段上注解的值,而不是获取注解类的值,
                // System.out.println("汽车的中文名字是:"+name.toString()); 
                // 输出的结果是: 汽车的中文名字是:@annontation.CarNameTarger(name=奔驰车)
                // 由此可知,getAnnotation();方法的用处  (重点)
                
                String carColour ="汽车的中文名:"+name.name();
                System.out.println(carColour);
            }
            else if(field.isAnnotationPresent(CarTypeTarger.class)){
                CarTypeTarger type= (CarTypeTarger) field.getAnnotation(CarTypeTarger.class);
                String carType="汽车的类型:"+type.carType().toString();
                System.out.println(carType);
            }
            else if(field.isAnnotationPresent(CarSalerTarger.class)){
                CarSalerTarger saler= (CarSalerTarger) field.getAnnotation(CarSalerTarger.class);
                String salerInfo=" 销售员姓名:"+saler.salername()+" 销售员年龄:"+ saler.age();
                System.out.println(salerInfo);
            }
        }
    }

}

第四步代码:测试:

@Test
public void testAnnoation(){
	CarInfoUtil.getFruitInfo(BenCar.class);
}

测试结果:

汽车的中文名:奔驰车
汽车的类型:benchi
销售员姓名:小华 销售员年龄:24

总结:参考链接:https://www.cnblogs.com/JackZed/p/6888668.html

1:关于获取类的字段有两种方式:getFields()和getDeclaredFields()。我们先来看看这两者的区别吧

getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。 
getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段

同样类似的还有getConstructors()和getDeclaredConstructors()、getMethods()和getDeclaredMethods(),这两者分别表示获取某个类的构造函数,方法。

获取字段的名称

String fieldName = field.getName();

获取字段的修饰符

int fieldValue = field.getModifiers();//如:private、static、final等

与某个具体的修饰符进行比较

Modifier.isStatic(fieldValue)//看此修饰符是否为静态(static)

获取字段的声明类型

field.getType();//返回的是一个class

与某个类型进行比较

field.getType() == Timestamp.class

获取指定对象中此字段的值

Object fieldObject= field.get(user);//user可以看做是从数据库中查找出来的对象

你可能感兴趣的:(实现自定义注解(代码篇))