Java 注解
一、概述
注解(Annotation)是Jdk5开始增加的对元数据(描述数据属性的信息)的支持,注解我们可以理解为标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行部署。注解和注释可不同,注释是给我们开发者看的,注解是给程序看的,
二、内置注解
@Override:定义在java.lang.Override中,用于修饰一个方法,表示重写父类中的方法。 @Deprecated:定义在java.lang.Deprecated中,用于修饰方法、属性、类,表示弃用或过时。 @SuppressWarnings:定义在java.lang.SuppressWadning中,表示忽略编译时的警告。
三、元注解
元注解就是注解其他注解的注解。
@Target:用于描述注解的使用范围。 @Retention:表示需要在什么级别保存改注解信息(Source,Class,RunTime) @Document:说明该注解将被包含在javadoc中。 @Inherited:标记这个注解是继承于哪个注解类。
四、认识注解
我们来拿@Deprecated这个注解来举例,看看它的源码结构。
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE}) public @interface Deprecated { }
第一行:@Documented 说明这个注解将被包含在javadoc中。
第二行:@Retention(RetentionPolicy.RUNTIME) 说明这个注解在运行时有效。
第三行:@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})说明这个注解的使用范围。
@Retention中参数如下:
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. * 注释将由编译器记录在类文件中,但不需要在运行时由 VM 保留。这是默认行为。 */ 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. * 注释将由编译器记录在类文件中,并在运行时由 VM 保留,因此可以反射性地读取它们。 * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
@Target中参数如下:
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ /** 类、接口(包括注解类型)或枚举声明 */ TYPE, /** Field declaration (includes enum constants) */ /** 字段声明(包括枚举常量)*/ FIELD, /** Method declaration */ /** 方法声明 */ METHOD, /** Formal parameter declaration */ /** 形式参数声明 */ PARAMETER, /** Constructor declaration */ /** 构造函数声明 */ CONSTRUCTOR, /** Local variable declaration */ /** 局部变量声明 */ LOCAL_VARIABLE, /** Annotation type declaration */ /** 注解类型声明 */ ANNOTATION_TYPE, /** Package declaration */ /** 包声明 */ PACKAGE, /** * Type parameter declaration * 类型参数声明 * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * 使用类型 * @since 1.8 */ TYPE_USE }
综合上面的参数我们可以知道 @**Deprecated **注解将被包含在javadoc中,在运行时有效,注解会被保留,可以声明在构造函数,字段,本地变量,方法,包,形式参数,类或接口中。
五、自定义注解
学习了上面的知识,我们可以很轻松的自定义一个注解,只需要按照内置注解照葫芦画瓢就可以啦。
自定义注解格式:
-元注解 -@interface 注解名称 { 定义内容 }
我们来定义一个Runtime注解,且只可以声明在方法和类中,并接收两个参数id和type。
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,ElementType.METHOD}) public @interface MyAnnotation { int id() default 0; String type(); }
其中接收int类型名为id的参数和String类型名为type的参数。default代表默认值。如果注解中的参数有默认值时,使用时可以不传此参数而使用默认值。
使用:
@MyAnnotation(id = 1,type = "这是类") public class MyTest { @MyAnnotation(type = "这是一个方法") public void test(){ } }
六、总结
到这里我们已经学会了java中的内置注解、元注解以及自定义注解,那么问题来了,如果自定义注解中传入了参数,那么这个参数如何获取呢?其实获取注解中的参数是通过反射来实现的