Java枚举类与注解

Java枚举类与注解

一、枚举类

1. 枚举类的使用

  1. 类的对象只有有限个,确定的。我们称此类为枚举类
  2. 当需要定义一组常量时,强烈建议使用枚举类
  3. 如果枚举类种只有一个对象,则可以作为单例模式的实现方式

2. 如何自定义枚举类(jdk5.0之前)

步骤

  1. 声明自定义枚举类对象的属性:private final

  2. 私有化类的构造器,并给对象属性赋值

  3. 提供当前枚举类的多个对象: public static final 的

  4. 其他诉求如: 获取枚举类对象的属性, toString方法等

    class Season {
          
          
    	//1.
        private final String seasonName;
        private final String seasonDesc;
    
        //2.
        private Season(String seasonName, String seasonDesc) {
          
          
            this.seasonName = seasonName;
            this.seasonDesc = seasonDesc;
        }
        
        //3.
        public static final Season SPRING = new Seanson("春天""春暖花开");
        public static final Season SUMMER = new Seanson("夏天""夏日炎炎");
        public static final Season AUTUMN = new Seanson("秋天""秋高气爽");
    	public static final Season WINTER = new Seanson("冬天""冰天雪地");
        
        //4.
        //getters(),toString()等方法
    }
    

3. *如何使用关键字enum定义枚举类(jdk5.0之后新增)

  • 使用enum关键字定义的枚举类,默认继承Enum类

步骤

  1. 提供当前枚举类的对象,多个对象逗号间隔,最后用分号结尾。

  2. 声明自定义枚举类对象的属性:private final

  3. 提供当前枚举类的多个对象: public static final 的

  4. 其他诉求如: 获取枚举类对象的属性, toString方法等

    enum Season {
          
          
        //1
        SPRING("春天","春暖花开"),
        SUMMER("夏天","夏日炎炎"),
        AUTUMN("秋天","秋高气爽"),
        WINTER("冬天","冰天雪地");
    
        //2.
        private final String seasonName;
        private final String seasonDesc;
    
        //3.
        private Season(String seasonName, String seasonDesc) {
          
          
            this.seasonName = seasonName;
            this.seasonDesc = seasonDesc;
        }
        //4.
        //getters(),toString()等方法
        //如获取季节信息
        public String getInfo() {
          
          
            return "Name:" + this.seasonName + "Desc:" + this.seasonDesc;
        }
    }
    
    public class enumTest {
          
          
        @Test
        public void test() {
          
          
            Season spring = Season.SPRING;
            System.out.println(spring.getInfo());
        }
    }//运行结果:Name:春天Desc:春暖花开
    

4. Enum类的主要方法

方法名 详细描述
value 返回枚举类型的对象数组。该方法可以方便的遍历所有的枚举值。
valueOf 传递枚举类型的 Class 对象和枚举常量名称给静态方法 valueOf, 会得到与参数匹配的枚举常量。
toString 得到当前枚举常量的名称。(可重写以增加易读性)
equals 枚举类型可直接使用 == 来比较两个枚举常量是否相等。Enum类种的equals方法就是用 == 实现的
hashCode Enum 实现了 hashCode() 来和 equals 保持一致。他也是不可变的.
getDeclaringClass 得到枚举常量所属枚举类型的 Class 对象。可以用他来判断两个枚举常量是否属于同一个枚举类型.
name 得到当前枚举常量的名称。建议优先使用toString()
ordinal 得到当前枚举常量的次序
compareTo 枚举类型实现了 Comparable 接口.可比较两个枚举类型的大小(按照声明的顺序排列)
clone 枚举类型不能被 Clone。为了防止子类实现克隆方法, Enum实现了一个仅抛出 CloneNotSupportedException 异常的不变clone()

5. 使用enum关键字实现接口的枚举类

  1. 情况一: 实现接口, 在enum类种实现抽象方法

    import org.junit.Test;
    import java.util.Arrays;
    import java.util.Comparator;
    
    public class enumTest {
          
          
        @Test
        public void test() {
          
          
    
        }
    }
    
    interface info {
          
          
        void show();
    }
    
    enum Season implements info{
          
          
    
        SPRING("春天","春暖花开"),
        SUMMER("夏天","夏日炎炎"),
        AUTUMN("秋天","秋高气爽"),
        WINTER("冬天","冰天雪地");
    
        private final String seasonName;
        private final String seasonDesc;
    
        private Season(String seasonName, String seasonDesc) {
          
          
            this.seasonName = seasonName;
            this.seasonDesc = seasonDesc;
        }
    
        @Override
        public void show() {
          
          
            System.out.println("这是Season枚举类");
        }
    }
    
    
    
    
  2. 情况二: 让枚举类的对象分别实现接口中的抽象方法

    import org.junit.Test;
    import java.util.Arrays;
    import java.util.Comparator;
    
    interface info {
          
          
        void show();
    }
    
    enum Season implements info{
          
          
        SPRING("春天","春暖花开"){
          
          
            @Override
            public void show() {
          
          
                System.out.println("春天在哪里");
            }
        },
        SUMMER("夏天","夏日炎炎"){
          
          
            @Override
            public void show() {
          
          
                System.out.println("宁夏");
            }
        },
        AUTUMN("秋天","秋高气爽"){
          
          
            @Override
            public void show() {
          
          
                System.out.println("秋天不回来");
            }
        },
        WINTER("冬天","冰天雪地"){
          
          
            @Override
            public void show() {
          
          
                System.out.println("大约在冬季");
            }
        };
    
        private final String seasonName;
        private final String seasonDesc;
    
        private Season(String seasonName, String seasonDesc) {
          
          
            this.seasonName = seasonName;
            this.seasonDesc = seasonDesc;
        }
    }
    
    public class enumTest {
          
          
        @Test
        public void test() {
          
          
            Season[] value = Season.values();
            for (int i = 0; i < value.length; i++) {
          
          
                value[i].show();
            }
        }
    }
    

二、注解(Annotation)

1. Annotation 概述

  1. 从 JDK 5.0 开始,Java 增加了对元数据(MetaData)的支持,也就是 Annotation(注解)
  2. Annotation 其实就是代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过使用 Annotation ,程序员可以再不改变原有逻辑的情况下,再源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过何写补充信息进行验证或者进行部署。
  3. Annotation 可以像修饰符一样被使用,可用于修饰包、类、构造器、方法、成员变量、参数、局部变量的声明,这些信息被包存再 Annotation 的"name = value"对中。
  4. JavaSE 中, 注解的使用目的比较简答,例如标记过时的功能,忽略警告等。再 Java EE/Android 中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替 JavaEE 旧版中所遗留的繁荣代码和 XML 配置等。
  5. 未来的开发模式都是基于注解的,JPA 是基于注解的,Spring2.5 以上都是基于注解的,Hibernate 3.x以后也是基于注解的,现在的Struts2 有一部分也是基于注解的了,注解是一种趋势,一定程度上可以说:框架 = 注解 + 反射 + 设计模式

2. 常见的 Annotation 示例

  • 使用 Annotation 时要在前面增加 @ 符号,并把该 Annotation 当成一个修饰符使用。用于修饰它支持的程序元素。

  • 部分生成文档相关的注解

    @author 标明开发该类模块的作者,多个作者之间使用,分割@version标明该类模块的版本
    @see参考转向,也就是相关主题

    @since从哪个版本开始增加的
    @param对方法中某参数的说明,如果没有参数就不能写
    @return对方法返回值的说明,如果方法的返回值类型是void就不能写
    @exception对方法可能抛出的异常进行说明,如果方法没有用throws显式抛出的异常就不能写

    • @param @return和@exception这三个标记都是只用于方法的。
    • @param的格式要求: @param 形参名 形参类型 形参说明
    • @return的格式要求: @return 返回值类型 返回值说明
    • @exception的格式要求: @exception 异常类型 异常说明
    • @param和@exception可以并列多个
  • 在编译时进行格式检查(JDK内置的三个基本注解)

    • @Override:限定重写父类方法,该注解只能用于方法
    • @Deprecated:用于表示所修饰的元素(类,方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
    • @SuppressWarnings:抑制编译起警告
  • 跟踪代码依赖性,实现替代配置文件功能

3. 自定义 Annotation

  1. 参照SuppressWarnings定义
  2. 定义新的 Annotation 类型使用 @interface 关键字
  3. 自定义注解自动继承 java.lang.annotation.Annotation 接口
  4. Annotation 的成员变量在 Annotation 定义中以无参方法的形式来声明。其方法名和返回值定义了该成员的名字和类型。我们称为配置参数。类型只能是八种基本数据类型、String类型、Class类型、Annotation类型、以上所有类型的数组
  5. 可以在定义 Annotation 的成员变量时为其指定初始值,指定成员变量的初始值可使用 default 关键字推荐
  6. 如果只有一个参数成员,建议使用参数名为value
  7. 如果定义的注解含有配置参数,那么使用时必须指定参数值,除非它有默认值。格式为 “ 参数名 = 参数值 “,如果只有一个参数成员,且名称为 value,可以省略 ” value= “
  8. 没有成员定义的 Annotation 称为标记
  9. 包括成员变量的 Annotation 称为元数据 Annotation
  10. 自定义注解必须配上注解的信息处理流程才有意义

4. JDK种的元注解

  • JDK 的元 Annotation 用于修饰其他 Annotation 定义

  • JDK 5.0 提供了4个标准的 meta-annotation 类型,分别是:

    • Retention:只用于修饰一个 Annotation 定义,用于指定该 Annotation 的生命周期,@Rentention 包含一个 RetentionPolicy 类型的成员边聊,使用@Rentention 时必须为该 value 成员变量指定值:

      • RetentionPolicy.SOURCE:在源文件中有效(即源文件保留),编译起直接丢弃这种策略的注释
      • RetentionPolicy.CLASS(默认行为):在 class 文件中有效(即 class 保留),当运行 Java 程序时,JVM 不会保留注释,这是默认值
      • RetentionPolicy.RUNTIME:在运行时有效(即运行时保留),当运行 Java 程序时,JVM 会保留注释。程序可以通过反射获取该注释。
    • Target:用于指定被修饰的 Annotation 能用于修饰哪些程序元素。@Target 也包含一个名为 value 的成员变量

      取值(ElementType) 取值(ElementType)
      CONSTRUCTOR 用于描述构造器 PACKAGE 用于描述包
      FIELD 用于描述域 PARAMETER 用于描述参数
      LOCAL_VARIABLE 用于描述局部变量 TYPE 用于描述类、接口(包括注解类型)或enum声明
      METHOD 用于描述方法
    • Documented:被它修饰的 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档。默认情况下,javadoc 是不包括注解的。

      • 定义为 Documented 的注解必须设置 Retention 值为 RUNTIME
    • Inherited:被它修饰的 Annotation 将具有继承性。如果某个类使用了被 @Inherited 修饰的 Annotation,则其子类具有该注解。

      • 比如:如果把表有 @Inherited 注解的自定义的注解标注在类级别上,子类则可以继承父类类级别的注解
      • 实际应用中,使用较少

5. 利用反射获取注解信息

6. JDK 8 中注解的新特性

  1. 可重复注解:如
    • 在 MyAnnotation 上声明 @Repeatable,成员值为 MyAnnotation.class
    • 要求:MyAnnotation 的 Target 和 Retention 等元注解与 MyAnnotation 相同
  2. 类型注解
    • ElementType.TYPE_PARAMETER:表示该注解能写在类型变量的声明语句中(如:泛型声明)
    • ElementType.TYPE_USE:表示该注解能写在使用类型的任何语句中

猜你喜欢

转载自blog.csdn.net/qq_40463117/article/details/113631142
今日推荐