Java 自定义注解

致敬。参考:https://www.cnblogs.com/acm-bingzi/p/javaAnnotation.html

一.注解的定义

    注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后某个时刻非常方便地使用这些数据。
    注解(Annotation)是java5开始引入的新特性,它们可以提供用来完整地描述程序所需的信息,而这些信息是无法用Java来表达的。因此,注解使的我们能够以将由编译器来测试和验证的格式,存储有关程序的额外信息。注解可以用来生成描述符文件,甚至或是新的类定义,并且有助于减轻编写“样板”代码的负担。通过使用注解,我们可以将这些元数据保存在Java源代码中,并利用annotation API为自己的注解构造处理工具,同时,注解的优点还包括:更加干净易读的代码以及编译期类型检查等。

二.注解的作用

    1.生成文档。这是最常见的,也是Java最早提供的注解。常见的注解有@param @return @see等
    2.跟踪代码依赖性,实现替代配置文件功能。
    3.在编译时进行格式检查。如@override放在方法前,如果这个方法并不是覆盖了超类方法,则编译时就能检查出。

三.注解的原理

    注解的本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy。通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValue的来源是Java常量池。

四.Java5内置注解(标准注解)

    Java5内置的三种注解,定义在java.lang中
    1.@Override,表示当前的方法定义将覆盖超类中的方法。如果不小心写错了,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示
    2.@Deprecated,如果程序员使用了注解为它的元素,那么编译器就会发出警告信息。
    3.@SuppressWarnings,关闭不当的编译器警告信息。在Java5之前的版本中,也可以使用该注解,不过会被忽略不起作用。

五.元注解

    1.@Target 表示该注解可以用在什么地方。可能的ElementType参数包括:
        1.1 CONSTRUCTOR 构造器的声明
        1.2 FIELD 域声明(包括enum实例)
        1.3 LOCAL_VARIABLE 局部变量声明
        1.4 METHOD 方法声明
        1.5 PACKAGE 包生命
        1.6 PARAMETER 参数声明
        1.7 TYPE 类,接口(包括注解类型)或emum声明
    2.@Retention 表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
        2.1 SOURCE 注解将被编译器丢弃
        2.2 CLASS 注解在class文件中可用,但会被VM丢弃
        2.3 RUNTIME VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息
    3.@Documented 将此注解包含在Javadoc中
    4.@Inherited 允许子类继承父类中的注解

六.测试

package com.yexiaobai.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Person {
	
	/**
	 * 姓名
	 * @return
	 */
	String name();
	
	/**
	 * 年龄
	 * @return
	 */
	int age();
}
package com.yexiaobai.annotation;

@Person(name="yexiaobai", age=20)
public class TestAnnotation {

	public static void print(Class clazz) {
		
		System.out.println(clazz.getName());
		
		Person person = (Person) clazz.getAnnotation(Person.class);
		if (person != null) {
			System.out.println("name==>" + person.name() + "==>age==>" + person.age());
		} else {
			System.out.println("person is no found!");
		}
	}
	
	public static void main(String[] args) {
		TestAnnotation.print(TestAnnotation.class);
	}
}

结果 

com.yexiaobai.annotation.TestAnnotation

name==>yexiaobai==>age==>20

 

 

你可能感兴趣的:(Ĵava)