1 . 什么是注解
注解即元数据,就是源代码的元数据,注解在代码中添加信息提供了一种形式化的方法,可以在后续中更方便的 使用这些数据,Annotation是一种应用于类、方法、参数、变量、构造器及包声明中的特殊修饰符。
注解可以用来生成文档;跟踪代码依赖性,实现替代配置文件功能,减少配置;在编译时进行格式检查;
2 . 元注解
在自己写注解之前首先了解下元注解,元注解的作用就是负责注解其他注解。
在java中有5个元注解
(1)@Target:用于描述注解的使用范围
ElementType.CONSTRUCTOR | 用于描述构造器 |
ElementType.FIELD | 用于描述属性 |
ElementType.LOCAL_VARIABLE | 用于描述局部变量 |
ElementType.METHOD | 用于描述方法 |
ElementType.ANNOTATION_TYPE | 用户描述注解 |
ElementType.PACKAGE | 用于描述包 |
ElementType.PARAMETER | 用于描述参数 |
ElementType.TYPE | 用于描述类、接口、注解、枚举 |
(2)@Retention:用于描述注解的生命周期
RetentionPolicy.SOURCE | 在源文件中有效 |
RetentionPolicy.CLASS | 在class文件中有效 |
RetentionPolicy.RUNTIME | 在运行时有效 |
(3)@Documented:顾名思义与文档有关,作用将注解包含在javadoc中
(4)@Inherited:允许子类继承父类中的注解
(5)@Repeatable:可重复注解。@Repeatable 是 Java 1.8 才加进来的。
3 . 自定义注解
自定义注解要注意一下几点:
(1)参数成员只能用八种基本类型和String,Enum,Class,annotations及这些类型的数组
(2)修饰符只能是public 或默认(default)
(3)注解元素必须有默认值,可以在注解中定义,也可以使用注解时指定
接下来就开始写一个类上方的注解,在运行时起作用,代码如下
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Animal{
public enum Color{GREEN,YELLOW,RED,BLACK}
String name();
int age() default 1;
Color color() default Color.BLACK;
}
还是用一个Dog类来作为例子,使用反射机制来提取注解,不懂反射的可以看我另一篇文章,首先可以通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解,然后通过 getAnnotation() 方法来获取 Annotation 对象或者getAnnotations() 方法,前一种方法返回指定类型的注解,后一种方法返回注解到这个元素上的所有注解。如果获取到的 Annotation 如果不为 null,则就可以调用它们的属性方法了,代码如下:
import java.lang.reflect.*;
@Animal(name = "旺财")
public class Dog{
private String name;
private Integer age;
private String color;
public Dog(){
}
public Dog(String name){
this.name = name;
}
public Dog(String name,Integer age,String color){
this.name = name;
this.age = age;
this.color = color;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public Integer getAge(){
return this.age;
}
public void setColor(String color){
this.color = color;
}
public String getColor(){
return this.color;
}
public void say(){
System.out.println("大家好我叫:" + name + "\t今年" + age + "岁了");
}
public static void main(String[] args){
try {
Class c = Class.forName("Dog");
System.out.println("----------注解----------");
//判断本类上是否有此注解
if(c.isAnnotationPresent(Animal.class)){
Animal anim = (Animal)c.getAnnotation(Animal.class);
System.out.println("名字为:" + anim.name() + "\t年龄为:" + anim.age() + "\t毛色为:" + anim.color());
}
} catch(Exception e){
e.printStackTrace();
}
}
}
运行结果:
最后总结一下,注解用起来方便快捷,但注解的提取需要借助于 Java 的反射技术,反射比较慢,所以注解使用时也需要谨慎计较时间成本。现在许多框架都是注解配置,如Spring系列,Spring Boot基于Spring框架所以更是有大量的注解,所以我们要了解注解。
希望本篇文章对您有所帮助!