Java中的注解开发

  1. 什么是注解
    语法:@注解名称

注解的作用:替代xml配置文件!

servlet3.0中,就可以不再使用web.xml文件,而是所有配置都使用注解!

注解是由框架来读取使用的!

  1. 注解的使用

    • 定义注解类:框架的工作
    • 使用注解:我们的工作
    • 读取注解(反射):框架的工作
  2. 定义注解类
    class A {}

interface A{}
enum A{}
@interface A{}//天下所有的注解都是Annotation的子类!

  1. 使用注解
    注解的作用目标:

    • 方法
    • 构造器
    • 参数
    • 局部变量
  2. 注解的属性

    • 定义属性:

    格式:

    @interface MyAnno1 {
    int age();
    String name();
    }
  • 使用注解时给属性赋值

    @MyAnno1(age=100, name="zhangSan")

  • 注解属性的默认值:在定义注解时,可以给注解指定默认值!

    int age() default 100;
    在使用注解时,可以不给带有默认值的属性赋值!

  • 名为value的属性的特权

    当使用注解时,如果只给名为value的属性赋值时,可以省略“value=”,例如: @MyAnno1(value="hello"),可以书写成 @MyAnno1("hello")

  • 注解属性的类型

    8种基本类型
    String
    Enum
    Class
    注解类型
    以上类型的一维数组类型

    当给数组类型的属性赋值时,若数组元素的个数为1时,可以省略大括号

@MyAnno1(
    a=100,
    b="hello",
    c=MyEnum1.A,
    d=String.class,
    e=@MyAnno2(aa=200, bb="world"),
    f=100
)

public class Demo3 {

}

@interface MyAnno1 {
    int a();
    String b();
    MyEnum1 c();
    Class d();
    MyAnno2 e();
    int[] f();
}
  1. 注解的作用目标限定以及保存策略限定
    6.1 让一个注解,它的作用目标只能在类上,不能在方法上,这就叫作用目标的限定!

    • 在定义注解时,给注解添加注解,这个注解是@Target
@Target(value={ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@interface MyAnno1 {
    
}

6.2 保留策略

  • 源代码文件(SOURCE):注解只在源代码中存在,当编译时就被忽略了
  • 字节码文件(CLASS):注解在源代码中存在,然后编译时会把注解信息放到了class文件,但JVM在加载类时,会忽略注解!
  • JVM中(RUNTIME):注解在源代码、字节码文件中存在,并且在JVM加载类时,会把注解加载到JVM内存中(它是唯一可反射注解!)

限定注解的保留策略

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno1 {
  
}
  1. 读取注解(反射)

========================

模拟注解的使用场景 解析注解

自定义一个注解类 :

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

//@Target(value={ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
//@Retention(value=RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value();
}

定义一个类, 使用自定义注解 :

// @MyAnnotation(value="Jack")
@MyAnnotation("Jack")
public class AnnotationClass {
    // 属性
    @MyAnnotation("itcast007")
    private String id;
    
    // 行为
    @MyAnnotation("Java")
    public void study() {
        System.out.println("好好学习, 天天向上!");
    }
}

定义一个测试类, 解析注解中的信息 :


1.import java.lang.reflect.Field;
2.import java.lang.reflect.Method;
3.
4.public class AnnotationDemo02 {
5.    public static void main(String[] args) throws Exception {
6.        
7.        // 1. 获取 AnnotationClass 类的字节码对象
8.        Class<?> cls = AnnotationClass.class;
9.        
10.        // 2. 获取类上的注解
11.        if (cls.isAnnotationPresent(MyAnnotation.class)) {
12.            MyAnnotation anno = cls.getAnnotation(MyAnnotation.class);
13.            String value = anno.value();
14.            System.out.println("类上的注解信息为 : " + value);
15.        }
16.        
17.        // 3. 获取属性上的注解
18.        Field field = cls.getDeclaredField("id");
19.        field.setAccessible(true);
20.        if (field.isAnnotationPresent(MyAnnotation.class)) {
21.            MyAnnotation anno = field.getAnnotation(MyAnnotation.class);
22.            String value = anno.value();
23.            System.out.println("属性上的注解信息为 : " + value);
24.        }
25.        
26.        // 4. 获取方法上的注解 
27.        Method method = cls.getMethod("study", new Class[]{});
28.        if (method.isAnnotationPresent(MyAnnotation.class)) {
29.            MyAnnotation anno = method.getAnnotation(MyAnnotation.class);
30.            String value = anno.value();
31.            System.out.println("方法上的注解信息为 : " + value);
32.        }
33.    }
34.}

结果为

类上的注解信息为 Jack
属性上的注解信息为  itcast007
方法上的注解信息为  java