Java注解

注解概述

  1. 注解的概念

    Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。

    注解和注释是完全不同的东西,注解会影响程序的运行。

    注释是给开发人员看的,不会影响程序的编译和运行。注解并不是给开发人员看的,是给程序看的,会影响程序的编译和运行。

  2. 注解的作用范围

    注解的作用范围由RUNTIME和SOURCE:

    • @WebServlet是在程序运行的时候起作用的,Java就把它的作用范围规定为RUNTIME

    • @Override是给编译器看的,编译器工作的时候识别出包含了@Override注解的方法,就去检查它上层父类的相应方法,存在则通过,否则报错。也就是说@Override在编译时起作用,Java就把它的作用范围规定为SOURCE

元注解

  1. 元注解@Target指定注解针对的地方:

  • ElementType.TYPE 针对类、接口

  • ElementType.FIELD 针对成员变量

  • ElementType.METHOD 针对成员方法

  • ElementType.PARAMETER 针对方法参数

  • ElementType.CONSTRUCTOR 针对构造器

  • ElementType.PACKAGE 针对包

  • ElementType.ANNOTATION_TYPE 针对注解

@Retention指定注解的保留域:

  • RetentionPolicy.SOURCE 源代码级别,由编译器处理,处理之后不再保留

  • RetentionPolicy.CLASS 注解信息保留到类对应的class文件中

  • RetentionPolicy.RUNTIME 由JVM读取,运行时使用

自定义注解

在自定义注解之前我们首先要明白注解的工作过程。注解名本身并不会提供任何实质功能,它只是作为一个标注,告诉程序在某个区域内有注解。真正产生作用的是我们通过反射机制去扫描各个区域是否拥有该注解,扫描到之后再进一步做出相应的动作。

自定义注解的基本流程如下:

  • 第一步,定义注解——相当于定义标记;

  • 第二步,配置注解——把标记打在需要用到的程序代码中;

  • 第三部,解析注解——在编译期或运行时检测到标记,并进行特殊操作。

下面我们来举个实例:

  1. 定义注解@InitMethod

     package com.jarreet.test;
     
     import java.lang.annotation.ElementType;
     import java.lang.annotation.Retention;
     import java.lang.annotation.RetentionPolicy;
     import java.lang.annotation.Target;
     
     @Target(ElementType.METHOD) // 作用在方法上
     @Retention(RetentionPolicy.RUNTIME) // 运行时生效
     public @interface InitMethod {
         
     }
  2. 定义一个类 InitDemo

     package com.jarreet.test;
     
     public class InitDemo {
         @InitMethod
         public void init(){
             System.out.println("init...");
        }
     
         public void test(){
             System.out.println("test...");
        }
     }
  3. 在Test类中通过反射实现@InitMethod的具体功能

     package com.jarreet.test;
     
     import java.lang.reflect.Method;
     
     public class Test {
         public static void main(String[] args) throws Exception {
             // 通过反射获取InitDemo及其所有方法
             Class clazz = Class.forName("com.jarreet.test.InitDemo");
             Method[] methods = clazz.getMethods();
             // 依次判断方法是否带有@InitMethod
             if(methods != null){
                 for (Method method : methods) {
                     boolean isInitMethod = method.isAnnotationPresent(InitMethod.class);
                     // 有带有@InitMethod,则执行该方法
                     if(isInitMethod){
                         method.invoke(clazz.getConstructor(null).newInstance(null),null);
                    }
                }
            }
        }
     }



posted @ 2021-05-06 00:34  离渊灬  阅读(55)  评论(0)    收藏  举报