目录

一、注解 Annotation

二、内置注解

三、元注解

测试元注解

四、自定义注解

测试自定义注解

五、反编译软件 XJad.exe

六、注解的解析

什么是注解的解析?

如何解析注解? 

七、解析注解案例

进行解析应用

八、应用场景

自定义一个注解

实现并测试


一、注解 Annotation

  • Annotation是从JDK5.0开始引入的新技术

  • Annotation的作用

    • 不是程序本身,可以对程序作出解释(这一点和注释(comment)没什么区别)

    • 可以被其他程序(比如:编译器等)读取

  • Annotation的格式:

  • 注解是以"@注释名"在代码中存在的,还可以添加一些参数值,例如:@SuppressWarnings(value="unchecked").

  • Annotation在哪里使用?

    • 可以附加在ackage,class,method,field 等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问

二、内置注解

  • @Override:定义在java.lang.Override 中,此注释只适用于修饰方法,表示一个方法声明打算重写超类中的另一个方法声明.

  • @Deprecated:定义在jaya.lang.Deprecated中,此注释可以用于修饰方法,属性,类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或者存在更好的选择

  • @SuppressWarnings:定义在java.ang.SuppressWarnings中,用来抑制编译时的警告信息口 与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数都是已经定义好了的我们选择性的使用就好了

    • @SuppressWarnings("all")

    • @SuppressWarnings("unchecked")V

    • @SuppressWarnings(value=f"unchecked","deprecation"

    • .....

三、元注解

  • 元注解的作用就是负责注解其他注解,Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明。

  • 这些类型和它们所支持的类在java.lang.annotation包,中可以找到.(@Target,@Retention@Documented ,@inherited )

  • @Target:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

  • @Retention:表示需要在什么级别保存该注释信息,用于描述注解的生命周期

    • SOURCE<CLASS <RUNTIME)

  • @Document:说明该注解将被包含在javadoc中

  • @Inherited:说明子类可以继承父类中的该注解

测试元注解

/**
 * 测试元注解
 * @author zhumq
 */
@MyAnnotation
public class myAnnotationTest {
    @MyAnnotation
    public void test() {

    }
}

// 自定义一个注解
// Target 表示元注解可以注解到哪些元素上
@Target(value ={ElementType.METHOD ,ElementType.TYPE})
// Retention 表示注解保留到哪个阶段,在什么地方还有效
// runtime>class>source
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
// Documented 表示注解是否可以生成在Java Doc文档中
@Documented
// Inherited 表示注解是否可以继承
@Inherited
@interface MyAnnotation {

}

四、自定义注解

  • 使用 @intrface自定义注解时,自动继承了java.lang.annotation.Annotation接口

  • 分析

    • @ interface用来声明一个注解,格式:public @ interface 注解名{定义内容}

    • 可以通过default声明参数的默认

    • 如果只有一个参数成员,一般参数名为value

    • 注解元素必须要有值,我们定义注解元素时,经常使用空字符串/0作为默认值

测试自定义注解

package com.dev.springBootDemo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.time.temporal.ValueRange;

/**
 * 自定义注解
 * @author zhumq
 * @date 2024/7/1 0:33
 */
public class MyAnnotationTest02 {
    // 进行赋值,若无,则需要有默认值
    @MyAnnotation02(name = "zhumq",schools = {"清华大学","北京大学"})
    // 如果只有一个参数,value可以省略 且必须是value
    @MyAnnotation03("zhumq")
    public void test(){
    }
}

@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation02 {
    // 注解的参数:参数类型 参数名 ();
    String name() default "";
    int age() default 0;
    int id() default -1; // 如果默认值为-1,则代表不存在
    String[] schools() ;
}

@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation03 {
    String value();
}

五、反编译软件 XJad.exe

六、注解的解析

什么是注解的解析?

  • 就是判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来。

如何解析注解? 

  • 指导思想:要解析谁上面的注解,就应该先拿到谁。
  • 比如要解析类上面的注解,则应该先获取该类的Class对象,再通过Class对象解析其上面的注解。
  • 比如要解析成员方法上的注解,则应该获取到该成员方法的Method对象,再通过Method对象解析其上面的注解。
  • Class 、Method、Field,Constructor、都实现了AnnotatedElement接口,它们都拥有解析注解的能力。

七、解析注解案例

package com.itheima.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author zhumq
 * @date 2024/7/2 0:08
 */
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest4 {
    String value();
    double aaa() default 100;
    String[] bbb();

}
package com.itheima.annotation;

/**
 * @author zhumq
 * @date 2024/7/2 0:10
 */
@MyTest4(value = "张三",aaa = 99.6, bbb = {"李四","王五"})
public class Demo {
    @MyTest4(value = "牛魔王",aaa = 99.7, bbb = {"周伯通","李逵"})
    public void test1(){}
}

进行解析应用

package com.itheima.annotation;

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author zhumq
 * @date 2024/7/2 0:13
 */
public class AnnotationTest3 {
    @Test
    public void parseClass() {
        // 1.获取class对象
        Class c = Demo.class;
        // 2.解析类上的注解
        // 判断类上是包含了某个注解
        if (c.isAnnotationPresent(MyTest4.class)) {
            MyTest4 myTest4 = (MyTest4) c.getDeclaredAnnotation(MyTest4.class);
            System.out.println(myTest4.value());
            System.out.println(myTest4.aaa());
            System.out.println(Arrays.toString(myTest4.bbb()));

        }
    }

    @Test
    public void parseMethod() throws Exception {
        // 1.获取class对象
        Class c = Demo.class;
        Method m = c.getDeclaredMethod("test1");
        // 2.解析方法上的注解
        // 判断方法上是包含了某个注解
        if (m.isAnnotationPresent(MyTest4.class)) {
            MyTest4 myTest4 = (MyTest4)m.getDeclaredAnnotation(MyTest4.class);
            System.out.println(myTest4.value());
            System.out.println(myTest4.aaa());
            System.out.println(Arrays.toString(myTest4.bbb()));

        }
    }

}
张三
99.6
[李四, 王五]
​
牛魔王
99.7
[周伯通, 李逵]

八、应用场景

自定义一个注解

package com.itheima.annotation2;
​
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 MyTest {
}

实现并测试

package com.itheima.annotation2;
​
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 * @author zhumq
 * @date 2024/7/2 0:27
 */
public class AnnotationTest4 {
​
//    @MyTest
    public void test1(){
        System.out.println("===test1===");
    }
    @MyTest
    public void test2(){
        System.out.println("===test2===");
    }
//    @MyTest
    public void test3(){
        System.out.println("===test3===");
    }
    @MyTest
    public void test4(){
        System.out.println("===test4===");
    }
​
    public static void main(String[] args) throws Exception {
        AnnotationTest4 a = new AnnotationTest4();
        // 1.获取class对象
        Class c = AnnotationTest4.class;
        // 2.获取所有方法
        Method[] m = c.getDeclaredMethods();
        // 3.便利这个数组中的每个方法,看方法上是否存在MyTest注解,若存在则执行
        for (Method method : m) {
            if (method.isAnnotationPresent(MyTest.class)) {
                // 说明该方法上有这个注解
                method.invoke(a);
            }
        }
​
    }
}
Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐