注解(Annotation)的使用.

1.什么是注解:

注释: 给程序员看的.
注解: 给JVM看的 , 可以加在包、类、字段、方法、局部变量、方法参数等前面 ,
         用来对这些元素说明 , 注释.
 
注: 一个同名的注解只能使用一次.

2.注解的作用:

  • 编写文档: 通过代码里标识的注解生成文档. [ 例: 生成doc文档 ]
  • 代码分析: 对代码进行分析. [ 例: 注解的反射 ]
  • 编译检查: 让编译器能够实现基本的编译检查. [ 例: Override ]

3.自定义注解:

定义格式:
       元注解
       public @interface 注解名称{
                  格式1: 修饰符 数据类型 属性名( );
                  格式2: 修饰符 数据类型 属性名( ) default 默认值 ;
       }
 
注解的属性:
       1.作用: 使用注解时可以传递参数 , 让注解功能更强大.
       2.属性使用的数据类型: 四类八种 , String类型 , Class 类型 , 枚举 , 注解类型.
       3.特殊属性Value : 当只有一个属性 && 名称是value , 可以直接给属性值.
 
使用格式:
       没有属性:  @注解名称
       有 属 性 :   @注解名称(属性名 = 属性值 , 属性名 = 属性值 … )
       value属性: @注解名称(属性值) ;

自定义注解案例:

/*
    定义一个注解:Book
        - 包含属性:String name()   书名
        - 包含属性:double price()  价格,默认值为 100
        - 包含属性:String[] authors() 多位作者
 */
public @interface Book {
    // 书名
    public abstract String name();
    
    //  - 包含属性:double price()  价格,默认值为 100
    public abstract double price() default  100;
    
    // - 包含属性:String[] authors() 多位作者
    public abstract String[] authors();
}

// 定义方法使用 
public class TestBook {
	// 有默认值的可以不传属性值 , 也可以传 . 
    @Book(name = "西游记" , authors = "孙悟空" ,price = 88.88)
    public void showBook(){

    }
}

4.注解之元注解: 用于修饰自定义的注解.

元注解之@Target:                                                         作用: 指明用在哪个位置.
可选参数值: ElementType(枚举类型.)
       type: 用在类 , 接口上 .
       field: 用在成员变量上 .
       method: 用在方法上 .
       parameter: 用在参数上 .
       constructor: 用在构造方法上.
       local_variable: 用在局部变量上.

元注解之@Retention:                                                 作用: 定义该注解的生命周期(有效范围)
可选参数值: RetentionPolicy:
       source: 只存在于java源代码中 .
       class: 存在于java源代码中 , 编译以后的字节码文件中
       runtime: 存在于java源代码中 , 编译后的字节码文件中 , 运行时内存中 . (可通过反射获取注解)

注解解析: 通过java技术获取注解数据的过程.
                看程序(就是获取注解的属性值)
isAnnotationPresent( ): 判断(类上,方法上…)是否有指定的注解
                     参数传递: 要判断注解的class文件对象
getAnnotation(): 获取(类上 ,方法上…)的注解.
                     参数传递: 要获取的注解的class文件对象.

综合案例:

/*
    反射和注解的综合练习题
        模拟注解@Test
        自定义一个注解@MyTest,并添加元注解(运行中有效,只能用在方法上)
        定义一个使用@MyTest类,定义多个方法,部分方法使用@MyTest注解
        获取测试类中所有的方法,判断方法上是否有@MyTest注解
            有:让方法执行  invoke(obj)
            没有:就不执行方法
 */
 
 // 自定义一个注解@MyTest,并添加元注解(运行中有效,只能用在方法上)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}

// 定义一个类 , 定义多个方法 , 部分方法使用MyTest注解 .
public class TestMyTest {
    @MyTest
    public void method01(){
        System.out.println("method01");
    }

    public void method02(){
        System.out.println("method02");
    }

    public void method03(){
        System.out.println("method03");
    }
    @MyTest
    public void method04(){
        System.out.println("method04");
    }
}

// 获取测试类中所有的方法,判断方法上是否有@MyTest注解
public class Demo01Annotation {
    public static void main(String[] args) throws Exception {
        // 创建class文件对象 .
        Class<?> clazz = Class.forName("demo07_annotation_$.TestMyTest");
        // 获取实例化对象.
        Object o = clazz.newInstance();
        // 获取测试类中所有的方法 .
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            // 判断方法上是否有@MyTest注解
            boolean b = method.isAnnotationPresent(MyTest.class);
            if(b){
                // 有:让方法执行  invoke(obj)
                Object o1 = method.invoke(o);
                System.out.println(o1);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42986107/article/details/82956501