1、自定义注解概述
自定义注解的三大步骤:
- 1、定义注解
- 2、使用注解
- 3、解析注解
1.1 定义注解
自定义注解和创建接口非常相似,但注解需要以@开头。方法体中的每一个方法实际上是声明了一个属性。其中,方法名是属性的名称;方法的返回值类型是属性的类型,属性的类型可以为:基本类型、String、enum、Class。在定义注解时也可以通过default来声明属性的默认值。
在定义注解时,通常使用元注解@Retention指定注解的保留策略。
在定义注解时,通常使用元注解@Target指定注解的作用对象。
1.2 使用注解
在定义完注解之后就在适当元素上使用注解了。
1.3解析注解
通常情况下,可在运行时解析自定义注解。
2 基本语法
注解类型的声明部分:
注解在Java中,与类、接口、枚举类似,因此其声明语法基本一致,只是所使用的关键字有所不同@interface。在底层实现上,所有定义的注解都会自动继承java.lang.annotation.Annotation接口。
public @interface CherryAnnotation {
}
注解类型的实现部分:
根据我们在自定义类的经验,在类的实现部分无非就是书写构造、属性或方法。但是,在自定义注解中,其实现部分只能定义一个东西:注解类型元素(annotation type element)。咱们来看看其语法:
public @interface CherryAnnotation {
public String name();
int age();
int[] array();
}
也许你会认为这不就是接口中定义抽象方法的语法嘛?别着急,咱们看看下面这个:
public @interface CherryAnnotation {
public String name();
int age() default 18;
int[] array();
}
看到关键字default了吗?这不是抽象方法。
注解里面定义的是:注解类型元素!
定义注解类型元素时需要注意如下几点:
- 1、访问修饰符必须为public,不写默认为public;
- 2、该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型(体现了注解的嵌套效果)以及上述类型的一位数组;
- 3、该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作);
- 4、()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法;
- 5、default代表默认值,值必须和第2点定义的类型一致;
- 6、如果没有默认值,代表后续使用注解时必须给该类型元素赋值。
3、在类上使用自定义注解
自定义注解:
package com.annotation2;
import java.lang.annotation.*;
/**
* Created with IntelliJ IDEA.
*
* @Author: Is good
* @Description:自定义注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation1 {
public String name();
public int age() default 20;
}
使用注解:
package com.annotation2;
/**
* Created with IntelliJ IDEA.
*
* @Author: Is good
* @Description:自定义注解
*/
@MyAnnotation1(name = "lucy", age = 22)
public class MyClass {
}
解析注解:
package com.annotation2;
/**
* Created with IntelliJ IDEA.
*
* @Author: Is good
* @Description:自定义注解
*/
public class TestAnnotation1 {
public static void main(String[] args) {
getAnnotation();
}
public static void getAnnotation() {
MyAnnotation1 annotation = null;
Class<?> clazz = MyClass.class;
// 判断注解是否存在
boolean isPresent = clazz.isAnnotationPresent(MyAnnotation1.class);
if (isPresent) {
// 获取注解
annotation = (MyAnnotation1) clazz.getAnnotation(MyAnnotation1.class);
System.out.println("annotation=" + annotation);
// 获取注解中属性的值
String name = annotation.name();
int age = annotation.age();
System.out.println("name=" + name + ",age=" + age);
} else {
System.out.println("Annotation is not present");
}
}
}
4、在字段上使用自定义注解
定义注解:
package com.annotation2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created with IntelliJ IDEA.
*
* @Author: Is good
* @Description:自定义注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation2 {
public String author();
}
使用注解:
package com.annotation2;
/**
* Created with IntelliJ IDEA.
*
* @Author: Is good
* @Description:自定义注解
*
*/
public class MyClass2 {
@MyAnnotation2(author = "is good")
public String message;
}
解析注解:
package com.annotation2;
import java.lang.reflect.Field;
/**
* Created with IntelliJ IDEA.
*
* @Author: Is good
*
* @Description:自定义注解
*/
public class TestAnnotation2 {
public static void main(String[] args) throws NoSuchFieldException {
MyAnnotation2 annotation = null;
Class<?> clazz = MyClass2.class;
// 获取字段
Field field = clazz.getDeclaredField("message");
// 判断注解是否存在
boolean isPresent = field.isAnnotationPresent(MyAnnotation2.class);
if (isPresent) {
// 获取注解
annotation = (MyAnnotation2) field.getAnnotation(MyAnnotation2.class);
System.out.println("annotation=" + annotation);
// 获取注解中属性的值
String author = annotation.author();
System.out.println("author=" + author);
} else {
System.out.println("Annotation is not present");
}
}
}