Android 学习(三):Java 注解

2021-09-26  本文已影响0人  翟小乙

上一篇 Android 学习(二):Java 反射

Java注解学习

学习内容

  1. 元注解
  2. 自定义注解
  3. 通过反射获取注解信息

Annotation通常在package,Class,Field,Method上,目的是与其他的类,成员变量,方法区分开来或者说做一个标识。

// 定义一个注解
public @interface MyTestApplication {

}
1. 元注解

JDK提供的几个特殊注解,只能用在注解上面

  1. ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
  2. ElementType.CONSTRUCTOR 可以构造方法进行注解
  3. ElementType.FIELD 可以给属性进行注解
  4. ElementType.LOCAL_VARIABLE 可给局部变量进行注解
  5. ElementType.METHOD 可给方法进行注解
  6. ElementType.PACKAGE 可给包进行注解
  7. ElementType.PARAMETER 可给一个方法内的参数进行注解
  8. ElementType.TYPE 可给一个类型进行注解,比如类,接口,枚举
例子:

例子前提:
-@Target是用在注解上,下面例子是注解所有没有问题
-ElementType内的标识,给注解进行详细说明

// 给注解设置一个元注解
@Target(ElementType.TYPE)  //并且设置该注解类型为类,接口,枚举等等
public @interface MyTestApplication {

}
@MyTestApplication   // 注解使用
public class Animal {
  private String name;
  public Animal () {
  }
  private void setName (String name) {
       this.name = name;
  }
  private String getName (){
      return this.name;
  }
}
  1. RetentionPolicy.SOURCE 注解只在源码阶段保留,编译器编译时它将被丢弃
  2. RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载JVM中
  3. RetentionPolicy.RUNTIME 注解可保留到程序运行时被加载到JVM中,因此可通过反射机制读取注解的信息
例子:

例子前提:
-@Retention是用在注解上,注解传递存活时间

-RetentionPolicy内的标识,给注解进行详细说明

@Target(ElementType.TYPE) //可给一个类型进行注解,比如类,接口,枚举
@Retention(RetentionPolicy.RUNTIME) //注解可保留到程序运行时被加载到JVM
public @interface MyTestApplication {

}
@MyTestApplication   // 注解使用
public class Animal {
  private String name;
  public Animal () {
  }
  private void setName (String name) {
       this.name = name;
  }
  private String getName (){
      return this.name;
  }
}
  1. 如父类Animal有一个注解@Test,且@Test 注解有@Inherited 注解,那么该父类Animal的子类Cat也默认有@Test注解
2. 自定义注解
public class Test {
// 注解可以显示赋值,如果没有默认值,必须给注解赋值
 @MyAnnotation (name = "注解传参",schools = {"西北大学", “西南大学”})
 public void test() {
     
}
}
// 声明一个注解 下面是 声明注解一个标准
@Target(ElementType.TYPE,ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
      // 注解的参数 : 参数类型 + 参数名 (); 也可以给默认值
      String name()  defalut "";
      int age() defalut 0;
      int id() defalut -1;// 如果默认值为 -1 ,代表不存在
      String[] schools() defalut {"西北", “西南”};
}
3. 通过反射获取注解信息
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassAnimalAnnotation {
           String value();
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnimalAnnotation {
           String dbName();
}
@ClassAnimalAnnotation(value = "db_animal")
public class Animal {
  @FieldAnimalAnnotation(dbName = "db_name")
  private String name;
  public void setName(String name) {
            this.name = name;
  }
  public void getName() {
          return this.name;
  }
}
public class RunAnimal {
      public  static void main(Strings[] args) {
        // 通过反射 获取 类对象
        Calss<?>  clas =  Class.forName("包名.Animal");
       // 通过类对象 获取注解 ===》 获取指定注解值

     // 1.获取类注解 肯定先获取到该类
      ClassAnimalAnnotation classAnimalAnnotation =(ClassAnimalAnnotation) clas .getAnnotation(ClassAnimalAnnotation.class);
      System.out.println(classAnimalAnnotation.value()) // 打印结果:db_animal
    // 2.获取属性注解 肯定先获取到该成员变量Field
                        // 方法一  
       Filed field = clas.getDeclaredField("name");
       FieldAnimalAnnotation fieldAnimalAnnotation =  field.getAnnotation(FieldAnimalAnnotation.class);
       System.out.println(fieldAnimalAnnotation .dbName()) // 打印结果:db_name
                        // 方法二 获取所有成员变量Field
      }
}

下一篇 Android 学习(四):Android APT/Android 编译时技术

上一篇 下一篇

猜你喜欢

热点阅读