注解

发布时间 2023-09-09 11:54:27作者: SimpleWord
title: 注解
index_img: https://tuchuangs.com/imgs/2023/08/14/ea3a278b72817316.png
tags:
  - Java SE
categories:
  - Java SE
excerpt: 注解

Annotation简述

就是Java代码里的特殊标记,比如:@Override@Test等,让其他程序根据注解信息来决定怎么执行该程序。

注解可以用在类上、构造器上、方法上、成员变量上、参数上、等位置处。【可以自己决定】

自定义注解

public @interface 名字{
  public 属性类型【任意】 属性名 default 默认值;
}
public @interface Simple {
    String name();

    int age() default 0; //有默认值,使用时可以不写

    String[] core();
}
@Simple(name = "java", age = 100, core = {"c", "c++"}) //用在类上
public class Main {
    public static void main(String[] args) {

    }

    @Simple(name = "java", age = 100, core = {"c", "c++"}) //用在方法上
    public static void method() {

    }
}

特殊属性

属性名:value

注解定义了value属性,如果没有其它属性,可以写XXX,否则要写value=xxx

image-20230813231200232

@Simple(name = "java", age = 100, core = {"c", "c++"}) //用在类上
public class Main {
    public static void main(String[] args) {

    }

    @Simple(name = "java", age = 100, core = {"c", "c++"}) //用在方法上
    @end(value = "10",size = 10) //Value必须写
    @Start("1") //相当于 value="1"
    public static void method() {

    }
}

注解的原理

上方Simple反编译

import java.lang.annotation.Annotation;

public interface Simple
	extends Annotation
{

	public abstract String name(); 

	public abstract int age();

	public abstract String[] core();
}
  • 注解的本质是接口,都继承自Annotation接口
  • 注解{….}是接口实现类

元注解

即修饰注解的注解。

image-20230813233819922

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

@Retention(RetentionPolicy.RUNTIME) //运行阶段
@Target({ElementType.PARAMETER, ElementType.TYPE})  //只能用在类和方法参数
public @interface Simple {
    String value() default "";
}
@Simple
public class Main {
    public void myMethod(@Simple String param) {

    }
}

注解的解析

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

image-20230813234352651

image-20230813234441887

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@interface MyAnnotation1 {
    String value() default "";

    String sex() default "男";
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@interface MyAnnotation2 {
    String value() default "";

    String sex() default "女";
}

// 使用定义的注解
@MyAnnotation1(value = "Class annotation1")
@MyAnnotation2(value = "Class annotation2")
class MyClass {

    @MyAnnotation1(value = "Method annotation1")
    @MyAnnotation2(value = "Method annotation2")
    public void myMethod() {
    }
}

public class Main {
    public static void main(String[] args) throws NoSuchMethodException {
        // 解析类上的指定注解
        MyAnnotation1 classAnnotation1 = MyClass.class.getDeclaredAnnotation(MyAnnotation1.class);
        System.out.println(classAnnotation1); //输出注解
        System.out.println(classAnnotation1.value() + " " + classAnnotation1.sex()); //输出它的值

        MyAnnotation2 classAnnotation2 = MyClass.class.getDeclaredAnnotation(MyAnnotation2.class);
        System.out.println(classAnnotation2);
        System.out.println(classAnnotation2.value() + " " + classAnnotation2.sex());

        System.out.println("---------------");

        // 解析类上的所有注解
        Annotation[] annotations = MyClass.class.getDeclaredAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        System.out.println("----------------");

        //是否有指定注解
        Class<MyClass> myClassClass = MyClass.class;
        if (myClassClass.isAnnotationPresent(MyAnnotation1.class)) {
            System.out.println("存在注解MyAnnotation1在类上");
        } else {
            System.out.println("不存在注解MyAnnotation1在类上");
        }

        System.out.println("---------------");

        // 解析方法上的指定注解
        Method method = MyClass.class.getDeclaredMethod("myMethod");
        MyAnnotation1 methodAnnotation = method.getDeclaredAnnotation(MyAnnotation1.class);
        System.out.println("Method annotation: " + methodAnnotation.value());
    }
}

image-20230814004609619

简易Junit

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {
    String value() default " ";
}

public class FalseJunit {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        FalseJunit falseJunit = new FalseJunit();

        //解析方法,如果有@Test注解,就执行

        Method[] methods = FalseJunit.class.getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(Test.class)) {
                Object invoke = method.invoke(falseJunit);
            }
        }
    }

    @Test
    public void Meth1() {
        System.out.println("自定义@Test注解方法1");
    }

    public void Meth2() {
        System.out.println("方法2");
    }

    @Test
    public void Meth3() {
        System.out.println("自定义@Test注解方法3");
    }

    public void Meth4() {
        System.out.println("方法4");
    }
}

image-20230814004003046