Java注解

目录

1. 认识注解

2. 定义注解

3. 元注解

4. 解析注解


1. 认识注解

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

写在接口、类、属性、方法上的一个标签,或者说是一个特殊形式的注释。在代码运行时通过反射读取并进行相应的操作。

比如:Junit框架的@Test注解可以用在方法上,用来标记这个方法是测试方法,被@Test标记的方法能够被Junit框架执行。

再比如:@Override注解可以用在方法上,用来标记这个方法是重写方法,被@Override注解标记的方法能够被IDEA识别进行语法检查。

2. 定义注解

Java注解_第1张图片

public @interface MyTest{
    String aaa();
    boolean bbb() default true;	//default true 表示默认值为true,使用时可以不赋值。
    String[] ccc();
}


@MyTest(aaa="牛魔王",ccc={"HTML","Java"})
public class AnnotationTest1{
    @MyTest(aaa="铁扇公主",bbb=false, ccc={"Python","前端","Java"})
    public void test1(){
        
    }
}

注解的属性名如果是value的话,并且只有value没有默认值,使用注解时value名称可以省略。比如现在重新定义一个MyTest2注解 。

public @interface MyTest2{
    String value(); //特殊属性
    int age() default 10;
}


@MyTest2("孙悟空") //等价于 @MyTest2(value="孙悟空")
@MyTest1(aaa="牛魔王",ccc={"HTML","Java"})
public class AnnotationTest1{
    @MyTest(aaa="铁扇公主",bbb=false, ccc={"Python","前端","Java"})
    public void test1(){
        
    }
}

注解本质时什么?

把注解的字节码进行反编译,使用XJad工具进行反编译。经过对MyTest1注解字节码反编译我们会发现:

  • MyTest1注解本质上是接口,每一个注解接口都继承子Annotation接口
  • MyTest1注解中的属性本质上是抽象方法
  • @MyTest实际上是作为MyTest接口的实现类对象
  • @MyTest(aaa="孙悟空",bbb=false,ccc={"Python","前端","Java"})里面的属性值,可以通过调用aaa()、bbb()、ccc()方法获取到。 【别着急,继续往下看,再解析注解时会用到】

Java注解_第2张图片

3. 元注解

元注解是修饰注解的注解。可以说是说明注解的一些属性。

Java注解_第3张图片

  • @Target是用来声明注解只能用在那些位置,比如:类上、方法上、成员变量上等
  • @Retetion是用来声明注解保留周期,比如:源代码时期、字节码时期、运行时期 

Java注解_第4张图片

4. 解析注解

我们可以通过反射技术把类上、方法上、变量上的注解对象获取出来,然后通过调用方法就可以获取注解上的属性值了。

我们把获取类上、方法上、变量上等位置注解及注解属性值的过程称为解析注解。

  • 如果注解在类上,先获取类的字节码对象,再获取类上的注解
  • 如果注解在方法上,先获取方法对象,再获取方法上的注解
  • 如果注解在成员变量上,先获取成员变量对象,再获取变量上的注解

总之:注解在谁身上,就先获取谁,再用谁获取谁身上的注解。

Java注解_第5张图片

案例:

Java注解_第6张图片 

@Target({ElementType.TYPE,ElementType.METHOD})   //注解用在类上和方法上
@Retention(RetentionPolicy.RUNTIME)              //注解保留到运行期
public @interface MyTest4 {

    String value();
    double aaa() default 100.00;
    String[] bbb();
}


@MyTest4(value="蜘蛛侠",aaa=99.9, bbb={"至尊宝","黑马"})
public class Demo4 {

    @MyTest4(value="孙悟空",aaa=199.9, bbb={"紫霞","牛夫人"})
    public void test1(){

    }
}

public class AnnotationTest4 {

    public static void main(String[] args) throws NoSuchMethodException {
        //1.获取Class对象
        Class c = Demo4.class;

        //2.解析类上的注解
        if(c.isAnnotationPresent(MyTest4.class)) {
            MyTest4 classAnno = c.getDeclaredAnnotation(MyTest4.class);
            System.out.println(classAnno.value());
            System.out.println(classAnno.aaa());
            System.out.println(classAnno.bbb());
        }

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

        //解析方法注解
        Method method = c.getDeclaredMethod("test1");
        if(method.isAnnotationPresent(MyTest4.class)) {
            MyTest4 methodAnno = method.getDeclaredAnnotation(MyTest4.class);
            System.out.println(methodAnno.value());
            System.out.println(methodAnno.aaa());
            System.out.println(methodAnno.bbb());
        }
    }
}

你可能感兴趣的:(Java面试指南,java,后端)