注解入门

1. 什么是注解
语法:@注解名称
注解的作用:替代xml配置文件!
servlet3.0中,就可以不再使用web.xml文件,而是所有配置都使用注解!
注解是由框架来读取使用的!

2. 注解的使用
  • 执行编译期的检查 例如:@Override
  • 分析代码(主要用途:替代配置文件); 写配置文件(xml), 注解开发(就是用注解代替配置文件)
3. 定义注解类
class A {}   //定义类
interface A{} //定义接口
enum A{}     //定义枚举
@interface A{}//所有的注解都是Annotation的子类!
4. 使用注解
注解的作用目标:
    • 方法
    • 构造器
    • 参数
    • 局部变量
 1 package Demo;
 2 
 3 
 4 @MyAnno1
 5 public class Demo1 {
 6     @MyAnno1
 7     private String name;
 8 
 9     @MyAnnol
10     public Demo1(){ }
11     
12     @MyAnnol
13     public void fun1() { }
14     
15     public void fun2(@MyAnno1 String name) {
16         @MyAnnol
17         String username = "hello";
18 
19 //        @MyAnno1
20 //        System.out.println("hello");//报错
21     }
22 }
23 //定义注解
24 @interface MyAnno1 { }
5. 注解的属性
  • 定义属性:
    • 格式:
@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时,可以省略大括号
 1 @MyAnno1(
 2         a=100,
 3         b="hello",
 4         c=MyEnum1.A,
 5         d=String.class,
 6         e=@MyAnno2(aa=100,bb="world"),
 7         f={"a1","a2"})
 8 public class Demo3 { }
 9 
10 @interface MyAnno1 {
11     int a();
12     String b();
13     MyEnum1 c();
14     Class d();
15     MyAnno2 e();
16     String[] f();
17 }
18 @interface MyAnno2 {
19     int aa();
20     String bb();
21 }
22 enum MyEnum1{A,B,C;}

6. 注解的作用目标限定以及保存策略限定

6.1 让一个注解,它的作用目标只能在类上,不能在方法上,这就叫作用目标的限定!

  • 在定义注解时,给注解添加注解,这个注解是@Target
@Target(value={ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@interface MyAnno1 {}
1 import java.lang.annotation.ElementType;
2 import java.lang.annotation.Target;
3 
4 @MyAnno1
5 public class Demo4 {}
6 @Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
7 @interface MyAnno1 {}

6.2 保留策略

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

  限定注解的保留策略

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno1 {}

7. 注解解析

java.lang.reflect.AnnotatedElement

  • T getAnnotation(Class<T>annotationType):得到指定类型的注解引用。没有返回null。

  • Annotation[] getAnnotations():得到所有的注解,包含从父类继承下来的。

  • Annotation[] getDeclaredAnnotations():得到自己身上的注解。

  • boolean isAnnotationPresent(Class<?extends Annotation> annotationType):判断指定的注解有没有。

    Class、Method、Field、Constructor等实现了AnnotatedElement接口.

import org.junit.Test;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;


public class Demo {
  @Test
  public void fun1() {
    //1. 得到作用目标
    Class<A> c = A.class;

    //2. 获取指定类型的注解
    MyAnno1 myAnno1 = c.getAnnotation(MyAnno1.class);
    System.out.println(myAnno1.name() + ", "
      + myAnno1.age() + ", " + myAnno1.sex());
  }

  @Test
  public void fun2() throws SecurityException, NoSuchMethodException {
    //1. 得到作用目标
    Class<A> c = A.class;
    Method method = c.getMethod("fun1");


    // 2. 获取指定类型的注解
    MyAnno1 myAnno1 = method.getAnnotation(MyAnno1.class);
    System.out.println(myAnno1.name() + ", "
      + myAnno1.age() + ", " + myAnno1.sex());
  }
}


@MyAnno1(name="A类", age=1, sex="男")
class A {
  @MyAnno1(name="fun1方法", age=2, sex="女")
  public void fun1() { }
}


@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno1 {
  String name();
  int age();
  String sex();
}


原文地址:https://www.cnblogs.com/gdwkong/p/8191406.html