注解解析:获取注解的属性值
使用反射技术:java.lang.reflect.AnnotatedElement接口
接口反射的实现类:
AccessibleObject, Class, Constructor, Field, Method, Package
抽象方法:
boolean isAnnotationPresent(Class annotationClass)
判断指定的类型(Constructor, Class, Method…)上,是否含有指定的注解
参数:
Class annotationClas:传递指定注解的Class文件对象;假如想判断有没有Book注解,传递Book.class
返回值:
boolean:含有指定的注解,返回true;没有指定的注解返回false
T getAnnotation(Class annotationClass)
获取指定的类型上(Constructor, Class, Method…)的注解
参数:
Class annotationClass:传递指定注解的Class文件对象;想获取Book注解,传递Book.class
返回值:
T:返回的就是指定的注解
注解不存在,返回null
元注解的使用:
package com.ccc.demo08Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.TYPE})//声明注解的使用位置:成员方法上,类/接口上
@Retention(RetentionPolicy.RUNTIME)//声明注解的声明周期(.java,.class,运行后的内存中)
public @interface Book {
//书名
public abstract String value();
//价格,默认值为 100
public abstract double price() default 100;
//多位作者
public abstract String[] authors();
}
元注解的解析:(解析方法上的注解、解析类上的注解)
package com.ccc.demo08Annotation;
import com.itheima.demo05Annotation.MyAnnotation01;
import com.itheima.demo05Annotation.MyAnnotation03;
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
@Book(value = "三国演义",price = 88,authors = "罗贯中")
public class ParseAnnotation {
@Book(value = "水浒传",authors = "施耐庵")
@MyAnnotation03("aaa")
public void method(){}
解析方法上的注解
分析:
- 获取当前类(ParseAnnotation)的class文件对象
- 获取当前类中的所有成员方法,返回一个Method数组
- 遍历数组,获取每一个Method对象
- 使用Method对象中的方法isAnnotationPresent判断,方法上是否有指定的Book注解
- 如果方法指定的Book注解,使用getAnnotation获取方法上指定的Book注解
- 使用注解名.属性名()获取注解的属性值
@Test
public void getAnnotationMethod() throws ClassNotFoundException {
//1.获取当前类ParseAnnotation的class文件对象
Class clazz = Class.forName("com.itheima.demo08Annotation.ParseAnnotation");
//2.获取当前类中的所有成员方法,返回一个Method数组
//Method[] methods = clazz.getMethods();
Method[] methods = clazz.getDeclaredMethods();
//3.遍历数组,获取每一个Method对象
for (Method m : methods) {
//System.out.println(m.getName()+"-->"+m.isAnnotationPresent(Book.class));
//4.使用Method对象中的方法isAnnotationPresent判断,方法上是否有指定的Book注解
if(m.isAnnotationPresent(Book.class)){
//5.如果方法指定的Book注解,使用getAnnotation获取方法上指定的Book注解
Book book = m.getAnnotation(Book.class);
//6.使用注解名.属性名()获取注解的属性值
System.out.println(book.value());
System.out.println(book.price());
System.out.println(Arrays.toString(book.authors()));
}
}
}
解析类上的注解
分析:
- 获取当前类(ParseAnnotation)的class文件对象
- 使用isAnnotationPresent判断类上是否有指定的Book注解
- 如果有Book注解,使用getAnnotation方法获取到Book注解
- 使用注解名.属性名(),获取注解的属性值
@Test
public void getAnnotationClass(){
//1.获取当前类ParseAnnotation的class文件对象
Class clazz = ParseAnnotation.class;
//2.使用isAnnotationPresent判断类上是否有指定的Book注解
boolean b = clazz.isAnnotationPresent(Book.class);
//System.out.println(b);
//3.如果有Book注解,使用getAnnotation方法获取到Book注解
if(b){
//Annotation是所有接口的父接口,而Annotation没有book类型的属性,
//所以得向下转型为book类型
Book book = (Book)clazz.getAnnotation(Book.class);
//4.使用注解名.属性名(),获取注解的属性值
String value = book.value();
System.out.println(value);
double price = book.price();
System.out.println(price);
String[] authors = book.authors();
System.out.println(Arrays.toString(authors));
}
}
}