注解概述
java注解(Annotation) 又称java标注,是JDK5.0引入的一种注释机制
java语言中的类,构造器,方法,成员变量,参数等都可以被注解进行标注
注解的作用是什么?
对java中类,方法,成员变量做标记,然后进行特殊处理,至于到底如何处理由业务需求决定
例如:JUnit框架中,标记了注解@Test的方法就可以被当成测试方法执行,而没有标记的就不能当测试方法执行
自定义注解
自定义注解就是自己做一个注解来使用
格式
public @interface 注解名称{
public 属性名称 属性名() default 默认值;
}
/**
* 自定义一个注解
*/
public @interface Mybook {
public String bookName();
public String author();
public double price();
}
主函数单纯说语法没有实际含义
@Mybook(bookName = "《java》",author = "张三",price = 20)
public class Test {
public static void main(String[] args) {
@Mybook(bookName = "《java》",author = "张三",price = 20)
int aaaa;
}
}
特殊属性
value属性,如果只有一个value属性的情况下,使用value属性的时候可以省略value名称不写
但是如果有多个属性,且多个属性没有默认值,那么value名称是不能省略的
public @interface Book {
public String value();//特殊属性
}
主函数
@Book("1111")
public class Test2 {
public static void main(String[] args) {
}
}
元注解
就是注解注解的注解
元注解常见有两个:
@Target :约束自定义注解只能放在哪些地方使用
可以使用的值在ElementType枚举了中常用的值如下
TYPE 类,接口
FIELD 成员变量
METHOD 成员方法
PARAMETER 方法参数
CONSTRUCTOR 构造器
LOCAL_VARIABLE, 局部变量
@Retention:申明注解的生命周期
可以使用的值定义在RetentionPolicy枚举类中
Source:注解只作用在源码阶段,生成的字节码文件中不存在
Class:注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值
Runtime:注解作用在源码阶段,字节码文件阶段,运行阶段(开发常用)
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD) //声明注解可以修饰的范围
@Retention(RetentionPolicy.RUNTIME) //声明注解可以长久存活
public @interface Mytest {
}
注解的解析
注解的操作中经常需要进行注解解析,注解的解析就是判断是否存在注解,存在注解就解析出内容
与注解解析相关的接口
Annotation:注解的顶级接口,注解都是Annotation类型的对象
AnnotationElement:该接口定义了与注解相关的解析方法
方法
Annotation[] getDeclaredAnnotations() 获取当前对象使用的所有注解,返回注解数组
T getDeclaredAnnotation(Class<T> annotationClass) 根据注解获取对象的注解对象
boolean isAnnotationPresent(Class<Annotation> annotationClass) 判断当前对象是否使用了指定的注解,如果使用了则返回True,否则返回 False
所有的类成分Class,Method ,Field ,Constructor,都实现了AnnotationElement接口,他们都具有解析注解的能力
注解解析的案例
需求:注解解析的案例
分析
1定义注解Book,要求如下
包含属性:String value() 书名
double price()价格,默认值100
String[] authors() 多位作者
限制注解的使用位置:类和成员方法上
指定注解的有效范围Runtime
2定义BookStore类,在类和方法上使用book注解
3定义AnnotationTest测试类获取Book注解的数据
创建注解
package 注解案例;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.invoke.MethodHandles.Lookup.ClassOption;
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Book {
String value();//书名
double price() default 100;
String[] authors();//多位作者
}
使用注解
package 注解案例;
@Book(value = "《java》",authors = {"张三","李四"})
public class BookStore {
@Book(value = "javaEE",authors = {"王五","赵六"})
public void start() {
System.out.println("开始售卖");
}
}
主函数
package 注解案例;
import java.lang.reflect.Method;
import java.util.Arrays;
public class AnnotationTest {
public static void main(String[] args) throws Exception {
Class c=BookStore.class;
//判断注解是否存在
if(c.isAnnotationPresent(Book.class)) {
Book b=(Book)c.getDeclaredAnnotation(Book.class);
System.out.println("书名"+b.value());
System.out.println("价格"+b.price());
System.out.println("作者:"+Arrays.toString(b.authors()));
}
else {
System.out.println("注解不存在");
}
System.out.println("--------------------------");
//解析方法上面的注解
Method m=c.getDeclaredMethod("start");
if(m.isAnnotationPresent(Book.class)) {
Book b2=(Book)m.getDeclaredAnnotation(Book.class);
System.out.println("书名"+b2.value());
System.out.println("价格"+b2.price());
System.out.println("作者:"+Arrays.toString(b2.authors()));
}
}
}