注解(三)之注解解析(解析方法上的注解、解析类上的注解)

注解解析:获取注解的属性值

使用反射技术: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(){}

解析方法上的注解
分析:

  1. 获取当前类(ParseAnnotation)的class文件对象
  2. 获取当前类中的所有成员方法,返回一个Method数组
  3. 遍历数组,获取每一个Method对象
  4. 使用Method对象中的方法isAnnotationPresent判断,方法上是否有指定的Book注解
  5. 如果方法指定的Book注解,使用getAnnotation获取方法上指定的Book注解
  6. 使用注解名.属性名()获取注解的属性值
    @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()));
            }
        }
    }

解析类上的注解
分析:

  1. 获取当前类(ParseAnnotation)的class文件对象
  2. 使用isAnnotationPresent判断类上是否有指定的Book注解
  3. 如果有Book注解,使用getAnnotation方法获取到Book注解
  4. 使用注解名.属性名(),获取注解的属性值
    @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));
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_45083975/article/details/91984693