01.注解

一.注解

  1. Java5开始,java开始对元数据的支持,也就是Annotation(注解)。

  2. 所有的Annotation都是java.lang.annotation.Annotation 接口的子接口,所以Annotation是一种特殊的接口(枚举也是特殊的类);

@interface Override {} ---> interface Override extends java.lang.annotation.Annotation{}

使用注解需要注意,必须有三方参与才有意义:

  1. :得有注解标签本身;
  2. :被贴的程序元素(类,字段,构造器,方法,参数上,包上等);
  3. :由第三方的程序使用反射的手段来赋予注解特殊的功能(也是Java代码).

二.元注解

  1. 注解:用来贴在类/方法/变量等之上的一个标记,第三方程序可以通过这个标记赋予一定功能

  2. 元注解:在定义注解的时候用来贴在注解上的注解,用来限定注解的用法

  3. 元注解有4个:
    @Retention、@Target、@Documented、@Inherited

@Documented	    表示注解会被javadoc指令编辑到API中
@Inherited      表示注解会遗传给子类

@Retention:决定注解可以保存到哪个时期

注解的有效期有3个都封装在枚举:RetentionPolicy中


RetentionPolicy.SOURCE:    表示注解只存在于源文件中,不会被编译到字节码中
RetentionPolicy.CLASS:       表示注解会被编译到字节码中,但是JVM不加载注解
RetentionPolicy.RUNTIME: 表示注解会被编译到字节中,会随着字节码的加载而进入JVM,因此可以反射性地读取(重)

不指定时,默认是RetentionPolicy.CLASS

@Target:决定了该注解可以贴在什么地方

可以贴注解的地方有很多,都封装在枚举:ElementType中
ElementType.TYPE                   贴在类、接口或枚举上(重)
ElementType.METHOD                 贴在方法上(重)
ElementType.FIELD                  贴在字段上(包括枚举常量,重)
ElementType.ANNOTATION_TYPE        贴在注解上
ElementType.CONSTRUCTOR            贴在构造方法上	
ElementType.LOCAL_VARIABLE         贴在局部变量上          
ElementType.PACKAGE                贴在包上(极少使用) 
ElementType.PARAMETER              贴在参数上 

三.注解的定义和使用

定义注解的语法:使用@interface 注解名称

public @interface VIP {
    //抽象方法 属性
}
//注解VIP
@Retention(RetentionPolicy.RUNTIME)//保留到运行时刻
@Target(ElementType.TYPE)//可以贴在类上
public @interface VIP {
	/**
	 * 属性的返回值类型只能是
	 * 基本类型/枚举/Class/注解/String/枚举以及他们各自的一维数组
	 */
	//Integer age1();//编译错误
	int age() default 17;//有一个int类型的参数,默认17
	String name();//一个String类型的参数
	Gender gender();//枚举
}

使用注解语法:

@注解名[(属性名=属性值,属性名=属性值)]
@VIP(name = "你好", age = 18, gender = Gender.MAN)
public class Person {
	// 只能贴在类上
	// @VIP(name="你好", age=18, gender=Gender.MAN)
	int age;
}

注意:给属性赋值时如果只有1个属性要赋值且名称叫value时,可以省略value不写 如:@VIP(“xxx”)

注意:属性的返回值类型只能是基本类型/枚举/Class/注解/String/枚举以及他们各自的一维数组

四.反射注解

思路:

  1. :获取注解所在类的字节码对象
  2. :在字节码中获取出注解对象
  3. :调用抽象方法获取注解属性的值
常用API:
Annotation[]  getAnnotations()  获取目标对象上所有的注解
Annotation  A  getAnnotation(Class<A> annotationClass)  获取目标对象上的注解,没有则返回null
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)  判断对象上是否有某种类型的注解 

//获取注解
public class AnnoDemo {
	public static void main(String[] args) throws Exception {
		//1)获取字节码
		Class clz = Class.forName("com.huangkun._02_anno.Person");
		//获取所有的注解对象 运行时期的 @Retention(RetentionPolicy.RUNTIME)
		Annotation[] anno = clz.getAnnotations();
		for (Annotation annotation : anno) {
			System.out.println(annotation);
		}
		//2)获取注解对象
		VIP vip = (VIP) clz.getAnnotation(VIP.class);
		System.out.println(vip);
		//3)获取注解属性
		System.out.println(vip.name());
		System.out.println(vip.age());
		System.out.println(vip.gender());
		//4)根据属性添加新功能
		if (vip.age() > 18) {
			System.out.println("请进");
		}else 
			System.out.println("禁止进入");
	}
}
发布了82 篇原创文章 · 获赞 0 · 访问量 1328

猜你喜欢

转载自blog.csdn.net/huang_kuh/article/details/105491637
01.