Java 注解

1585364631
2023-02-20 / 0 评论 / 167 阅读 / 正在检测是否收录...

Java 注解

注解(Annotation)

  • 就是Java代码里的特殊标记,比如:@Override、@Test等,作用是:让其他程序根据注解信息来决定怎么执行该程序。
  • 注意:注解可以用在类上、构造器上、方法上、成员变量上、参数上等位置

自定义注解

  • 自己定义注解
  • value: 特殊属性,只有一个value参数(或者其他参数有默认值)可以直接省略value写值
    模板:
  public @interface 注解名称{
        public 属性类型 属性名() default 默认值;
    }

案例

@interface MyTest1 {
    String aaa();
    boolean bbb() default true;
    String[] ccc();
}
@interface MyTest2 {
    String value(); //特殊属性,只有一个value参数(或者其他参数有默认值)可以直接省略value写值
}
@interface MyTest3 {
    String value(); //特殊属性,只有一个value参数(或者其他参数有默认值)可以直接省略value写值
    int age() default 1;
}

@MyTest1(aaa = "类注解",ccc = {"a","b","c"})
public class AnnotationTest1 {
    @MyTest1(aaa = "函数注解",ccc = {"aa","bb","cc"})
    public void test1(){

    }
    @MyTest2("只有一个value参数(或者其他参数有默认值)可以直接省略value写值2")
    public void test2(){

    }
    @MyTest3("只有一个value参数(或者其他参数有默认值)可以直接省略value写值3")
    public void test3(){

    }
}

注解的原理

  • 可以查看注解编译后的文件,本质上是接口,里面写的一些属性都是抽象方法
    字节码文件
@interface MyTest1 {
    String aaa();

    boolean bbb() default true;

    String[] ccc();
}

@interface MyTest2 {
    String value();
}

@interface MyTest3 {
    String value();

    int age() default 1;
}

元注解

  • 指的是修饰注解的注解
  • 常见的元注解:@Target、@Retention

@Target 声明被修饰的注解只能在哪些位置使用

  • @Target(ElementType.TYPE)
  • TYPE,类,接口
  • FIELD,成员变量
  • METHOD,成员方法
  • PARAMETER,方法参数
  • CONSTRUCTOR,构造器
  • LOCAL_VARIABLE,局部变量
@Target(ElementType.TYPE) // 当前被修饰的注解只能在类上使用
@interface MyTest4{

}

@Target({ElementType.TYPE,ElementType.METHOD}) // 当前被修饰的注解只能在类和方法上使用
@interface MyTest5{

}

@Retention 声明注解的保留周期

@Retention()

  • SOURCE 只作用在源码阶段,字节码文件中不存在
  • CLASS(默认值) 保留到字节码文件阶段,运行阶段不存在
  • RUNTIME(开发常用) 一直保留到运行阶段
@Retention(RetentionPolicy.SOURCE)//只作用在源码阶段,字节码文件中不存在
@interface MyTest6 {
}

@Retention(RetentionPolicy.CLASS)//保留到字节码文件阶段,运行阶段不存在
@interface MyTest7 {
    
}

@Retention(RetentionPolicy.RUNTIME)//一直保留到运行阶段
@interface MyTest8 {

}

注解的解析

  • 判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来
  • 使用反射
package Annotations;
import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.util.Arrays;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyTestAnnotation {
    String value();
    double aaa() default 100;
    String[] bbb();
}

@MyTestAnnotation(value = "类注解",aaa = 99.5,bbb = {"a","b"})
class TestClass {
    @MyTestAnnotation(value = "方法注解",aaa = 199.5,bbb = {"b","a"})
    public void test1(){

    }
}

public class MyTestClass{


    public static void main(String[] args) throws Exception{
        {
            // 1.获取class对象
            Class c = TestClass.class;
            // 2.解析类上的注解
            // 判断类上是否包含了某个注解
            if (c.isAnnotationPresent(MyTestAnnotation.class)){
                MyTestAnnotation myTestAnnotation = (MyTestAnnotation) c.getDeclaredAnnotation(MyTestAnnotation.class);
                System.out.println(myTestAnnotation.value());
                System.out.println(myTestAnnotation.aaa());
                System.out.println(Arrays.toString(myTestAnnotation.bbb()));
            }
        }
        System.out.println("--------------------------");
        {
            // 1.获取class对象
            Class c = TestClass.class;
            Method m = c.getDeclaredMethod("test1");
            // 2.解析方法上的注解
            // 判断方法上是否包含了某个注解
            if (m.isAnnotationPresent(MyTestAnnotation.class)){
                MyTestAnnotation myTestAnnotation = (MyTestAnnotation) m.getDeclaredAnnotation(MyTestAnnotation.class);
                System.out.println(myTestAnnotation.value());
                System.out.println(myTestAnnotation.aaa());
                System.out.println(Arrays.toString(myTestAnnotation.bbb()));
            }
        }
    }
}

输出结果

类注解
99.5
[a, b]
--------------------------
方法注解
199.5
[b, a]
0

评论 (0)

取消