high-level——注解和枚举(13)

一、注解

  • 它是 jdk1.5 的新特性,它应用在类、接口及枚举等方面,它的作用就是打标记,它不能执行。
  1. jdk 的基础注解

    • Deprecated 表示类的成员已过时,不建议使用。
    • SuppressWarnings 让编译器不要输出警告信息。
    • Override
  2. 用于注解的注解,元注解

    • Target 它规定被修饰的注解可以使用在类的哪种成员上,比如类上,方法上,字段上等。
    • Retention 它规定被修饰的注解在哪个阶段起作用,比如源代码编写阶段,编译阶段,运行时阶段。
  3. 注解的来源

    • 来源于 jdk ,对基础编程有作用。
    • 来源于框架,对于实现框架的功能或应用程序的功能起作用。在使用框架的早期,都是用配置文件来写配置信息,可以把配置信息与源程序分开,实现解耦,让程序结构良好。但是工作量会大,为了让写配置变得更简单方便,出现了注解的应用,它减少了配置工作量,在程序中使用注解是当前所有框架推荐的方式。但是有一小部分的配置没有注解可以替代,因此现代的基于框架的程序开发即会写配置,又要用注解。
  4. 自定义注解

    • 通过自己设计注解来了解注解的工作方式及使用方法。

    • 创建注解

    • 在新的注解上使用 @Retention() 注解,该注解要求指定一个属性值,取值来自于 RetentionPolicy 的枚举类型,该枚举定义了三个常量

      • SOURCE:将被编译器丢弃,指定新注解只能应用在代码的编写阶段,java 程序的开发工具会对这种注解进行解释并处理。
      • CLASS:将由编译器记录在类文件中,但 jvm 不需要在运行时保留,在编译期起作用,编译器会解释并处理。
      • RUNTIME:将由编译器记录在类文件中,并由 jvm 在运行时保留,因此可以反射读取。
    • 综上可见,第一开发工具不是我们写的,编译器也不是我们设计的,对于SOURCE和CLASS指定的阶段,我们自定义注解起不了作用,只有JDK提供的注解才能起作用。我们自定义的往解只能在运行时起作用,因为可能利用反射技术去读取并解释。因此,所有框架提供的注解只能在运行时起作用。

    • 在新的注解上使用 @Target() 元注解,该注解规定被指定的注解的使用位置,比如方法上,类上,字段等。

      • ElementType 枚举提供了该注解可以使用的属性值
      • TYPE:规定注解只能使用在类上
      • METHOD:只能使用在方法上
      • FIELD:只能使用在字段上
    • 注解可以带有属性,也可以没有属性

      • 如果注解的作用很单一,可以不写属性
      • 如果注解的作用很复杂,也就是在其表达的功能上有很多细分项目,就必须要使用属性,属性可以有多个。
    • 属性的分类

      1. 名称为 value 的属性为默认属性,指定该属性时可以不用指定属性名称(没有指定其它的属性),如,String value() default “default”;(default 属性默认取值)
      2. 名称不为 value 的属性为一般属性,指定一般属性的值时一定要带有属性名称
    • 自定义注解本身没有任何作用,但通过反射技术读取到该注解,然后依据注解的规定来实现不同的功能。

    • 框架如果提供了注解,就必须要提供对注解的读取和解释的程序,以便让注解发生作用。

      package com.zhong;
      
      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.METHOD)//注解使用在方法上
      
      public @interface MyAnnotation {
          String value() default "default";//默认属性
      
          int[] ary() default {};//一般属性
      }
      
      package com.zhong.test_8;
      
      import com.zhong.MyAnnotation;
      
      public class AnnotationTest {
          @MyAnnotation(value = "abc", ary = {1, 2, 3})
      
          public void annotationUse(String name) {
              System.out.println("依照注解属性传入的参数值:" + name);
          }
      }
      
      package com.zhong.test_8;
      
      import com.zhong.MyAnnotation;
      
      import java.lang.reflect.Method;
      
      //采用反射读取注解并解释执行的方式
      public class UseAnnotation {
          public static void main(String[] args) throws Exception {
              Class<?> aClass = Class.forName("com.zhong.test_8.AnnotationTest");
              Method method = aClass.getMethod("annotationUse", String.class);
              /*Annotation[] annotations = method.getDeclaredAnnotations();
              for (Annotation annotation : annotations) {
                  System.out.println(annotation.annotationType().getName());
              }*/
              AnnotationTest o = (AnnotationTest) aClass.newInstance();
              MyAnnotation annotation = method.getDeclaredAnnotation(MyAnnotation.class);
              if (annotation != null) {//成立就表示注解被读取了
                  String value = annotation.value();
                  int[] ary = annotation.ary();
                  for (int i : ary) {
                      System.out.print(i + " ");
                  }
                  method.invoke(o, value);
                  //System.out.println(value);
      
              }
          }
      }
      

二、枚举

  • 我们在编程过程中,需要用一个变量的值来表示星期几。

    package com.zhong.test_8;
    
    //枚举是一种特殊的类型,它具有有限个的元素,这些元素是本类型的对象
    public enum WeekDay {
        SUN(0), MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6);//枚举的元素,必须出现在最前面,元素的类型就是本枚举的类型
        //枚举可以有成员变量
        private int index;
    
        //枚举可以有私有的构造方法
        WeekDay() {
        }
        
        WeekDay(int index) {
            this.index = index;
        }
        
        public int getIndex() {
            return index;
        }
    }
    
    package com.zhong.test_8;
    
    public class EnumDemo {
        public static void main(String[] args) {
            WeekDay day1 = WeekDay.SUN;
            WeekDay day2 = WeekDay.MON;
            WeekDay day3 = WeekDay.TUE;
            System.out.println(day1.getIndex());
            System.out.println(day2.getIndex());
            System.out.println(day3.getIndex());
        }
    }
    
上一篇:HGDB兼容MySQL date_format函数


下一篇:枚举原理Enum