了解注解
注解是Java1.5,JDK5.0引用的技术,与类,接口,枚举处于同一层次 。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释 。
在Java中,自带了三种注解,这三种注解存在于java.lang包中,首先我们讲一讲这些注解
- Override——它的作用是对覆盖超类中方法的方法进行标记,如果被标记的类并没有实际覆盖超类,则编译器会发出错误警告。
很常见的一个注解,了解JavaOOP的小伙伴这个注解应该较为常用,告诉编译器,我这个方法是重写了父类方法,当然如果你的方法并没有实际重写父类方法时,那么编译器就会显示警告信息 - Deprecated——它的作用是对不应该再使用的方法添加注解,当编程人员使用这些方法时,将会在编译时显示提示信息
当一个方法名或者类名上面此注解之后,编译器会认为这个方法属于过期方法,明显的区别在于类名或者方法名上会画一道删除线,标识过期方法不影响方法的继续使用 - SuppressWarnings——这个仅仅是告诉编译器忽略特定的警告信息,例如在泛型中使用原生数据类型
例如我们在使用一些以Deprecated注解的方法时,编译器会提出黄线警告,那么只要在使用的地方加上@SuppressWarnings(“deprecation”)就可以使编译器忽略这个警告
此注释常用的参数值有 : deprecation(忽略使用过时类或者方法),unchecked(忽略执行了未检查装换时警告) , fallthrough(忽略switch直接指向到下一个case块没有break警告),path(忽略类路径,源文件路径中有不存在路径时警告),serial(忽略可序列化类中没有serialVersionUID时的警告),finally(任何finally不能正常执行时的警告),all(以上所有)
自定义注解须知
首先,自定义注解我们必须了解四个元注解,什么是元注解?元注解指作用于注解之上的元数据或者元信息,简单通俗的讲,元注解就是注解的注解 .
- Documented——指明拥有这个注解的元素可以被javadoc此类的工具文档化。这种类型应该用于注解那些影响客户使用带注释的元素声明的类型。如果一种声明使用Documented进行注解,这种类型的注解被作为被标注的程序成员的公共API 。
- Inherited——指明该注解类型被自动继承。如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,那么也将自动查询当前类的父类是否存在Inherited元注解,这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类。
- Retention——指明在什么级别显示此注解
- Target——指明该类型的注解可以注解的程序元素的范围
Documented与Inherited是典型的标识性注解,也就是说在注解内部并没有成员变量,没有成员变量的注解称为标识注解
Target主要的参数类型包括以下几种
- ElementType.TYPE 用于类,接口,枚举但不能是注解
- ElementType.FIELD 作用于字段,包含枚举值
- ElementType.METHOD 作用于方法,不包含构造方法
- ElementType.PARAMETER 作用于方法的参数
- ElementType.CONSTRUCTOR 作用于构造方法
- ElementType.LOCAL_VERIABLE 作用于本地变量或者catch语句
- ElementType.ANNOTATION_TYPE 作用于注解
- ElementType.PACKAGE 作用于包
Retention主要的参数类型包括以下几种
- RetentionPolicy.SOURCE 注解存在于源代码中,编译时会被抛弃
- RetentionPolicy.CLASS 注解会被编译到class文件中,但是JVM会忽略
- RetentionPolicy.RUNTIME JVM会读取注解,同时会保存到class文件中
自定义注解
注解的定义
注解中可以定义的数据类型是受到限制的,除了基本类型之外,String,Enums,Annotation,Class以及这些类型的数组
package com.deng.spring; import org.springframework.context.annotation.Scope; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** 用于指定该注解的作用范围,可以指定一个或者多个 ElementType.TYPE 用于类,接口,枚举但不能是注解 ElementType.FIELD 作用于字段,包含枚举值 ElementType.METHOD 作用于方法,不包含构造方法 ElementType.PARAMETER 作用于方法的参数 ElementType.CONSTRUCTOR 作用于构造方法 ElementType.LOCAL_VERIABLE 作用于本地变量或者catch语句 ElementType.ANNOTATION_TYPE 作用于注解 ElementType.PACKAGE 作用于包 */ @Target({ElementType.TYPE,ElementType.METHOD}) /** * 定义该注解的作用域 * RetentionPolicy.SOURCE 注解存在于源代码中,编译时会被抛弃 RetentionPolicy.CLASS 注解会被编译到class文件中,但是JVM会忽略 RetentionPolicy.RUNTIME JVM会读取注解,同时会保存到class文件中 */ @Retention(RetentionPolicy.RUNTIME) //@interface定义注解的关键词 //注解的名称为Animal public @interface Animal { /** //定义成员变量 语法为 数据类型 成员变量名() default 默认值; //成员变量可以通过default指定默认值 //如果成员变量不指定默认值的情况下 //我们在使用注解时则必须给没有默认值的成员变量赋值 PS: 成员变量名为value时,使用注解的时候可以不指定成员变量名,直接设置一个值 注解中成员变量可以定义的数据类型是受到限制的,除了基本类型之外,String, Enums,Annotation,Class以及这些类型的数组 */ String value() ; public String color() ; }
注解的使用
package com.deng.spring; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; @Animal(value = "dog",color = "red") public class Dog { private String name; }
注解的解析
Class c = Dog.class; Annotation[] as = c.getAnnotations(); for(Annotation a : as){ if(a instanceof Animal){ Animal am = (Animal)a; //获取成员变量的值 System.out.println("value = " + am.value()); System.out.println("color = " + am.color()); } }