首页 > 技术文章 > Java枚举类和注解

th1024 2021-01-29 21:44 原文

Java枚举类和注解

枚举类

1. 说明

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

2. 自定义枚举类步骤

class Season{
    //1. 声明Season对象的属性:private final修饰
    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 Season("春天","春暖花开");
    public static final Season SUMMER = new Season("夏天","夏日炎炎");
    public static final Season AUTUMN = new Season("秋天","秋高气爽");
    public static final Season WINTER = new Season("冬天","冰天雪地");

    //4. 其它诉求1:获取枚举类对象的属性
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    //5. 其他诉求2:输出枚举类对象的信息
    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}

3. enum关键字定义枚举类

/使用enum关键字枚举类
enum Season1 {
    //1. 提供当前枚举类的多个对象,多个对象之间用','隔开,末尾对象';'结束
    SPRING ("春天","春暖花开"),
    SUMMER ("夏天","夏日炎炎"),
    AUTUMN ("秋天","秋高气爽"),
    WINTER ("冬天","冰天雪地");

    //1. 声明Season对象的属性:private final修饰
    private final String seasonName;
    private final String seasonDesc;

    //2. 私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //4. 其它诉求1:获取枚举类对象的属性
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }


}

4. enum关键字定义枚举类之后的常用方法(继承于java.lang.Enum类)

Season1 summer = Season1.SUMMER;
        //toString():返回枚举类对象的名称
        System.out.println(summer);

//        System.out.println(Season1.class.getSuperclass());
        System.out.println("**************************");
        //values():返回所有的枚举类对象构成的数组
        Season1[] values = Season1.values();
        for (int i = 0; i < values.length; i++) {
            System.out.println(values[i]);

        }
        System.out.println("**************************");
        Thread.State[] values1 = Thread.State.values();
        for (int i = 0; i < values1.length; i++) {
            System.out.println(values1[i]);
        }
        System.out.println("****************************");
        //valueOf(String objName):返回枚举类中对象名是objName的对象
        Season1 winter = Season1.valueOf("WINTER");
//        Season1 winter = Season1.valueOf("WINTER1");//IllegalArgumentException
        System.out.println(winter);

5. 枚举类对象分别实现接口

interface info{
    void show();
}

//使用enum关键字枚举类
enum Season1 implements info{
    //1. 提供当前枚举类的多个对象,多个对象之间用','隔开,末尾对象';'结束
    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("雪花飘飘北风萧萧");
        }
    };
}

注解

1. 注解的理解

  • JDK5.0新增的功能
  • Annotation是代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理
  • 通过使用Annotation,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息
  • 在JavaSE中,注解的使用目比较简单,例如标记过时功能,忽略警告等。
  • 在JavaEE/Android中注解占据了更重要的角色,例如用来配置应程序的任何切面,代替JavaEE繁冗代码和XML配置等

框架 = 注解 + 反射机制 + 设计模式

2. 使用示例

  • 示例一:生成文档相关的注解

  • 示例二:在编译时进行格式检查(JDK内置的三个基本注解)

    • @Override: 限定重写父类方法 , 该注解只能用于方法

    • @Deprecated :用于表示所修饰的元素(类, 方法等)已过时。通常是因为所修饰的结构危险或存在更好选择

    • @SuppressWarnings : 抑制编译器警告

  • 示例三:跟踪代码依赖性,实现替代配置文件功能

3. 自定义注解

参照@SuppressWarnings定义

说明:

  • 使用@interface关键字定义
  • 内部定义成员,通常用value表示
  • 可以指定成员的默认值,使用default定义
  • 如果自定义注解没有成员,表明是一个标识作用

如果注解有成员,在使用注解时,需指定成员的值

自定义注解必须配上注解的信息处理流程(使用反射)才有意义

自定义注解通常都会指明两个元注解:Retention、Target

package com.th1024.Annotation;

import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;

/**
 * @author TuHong
 * @create 2021-01-29 14:03
 */

@Inherited
@Repeatable(MyAnnotations.class)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String value() default "hello";
}

4. 元注解

JDK提供的四种元注解

  • 元注解:对现有的注解进行解释说明的注解
  • Retention:指定所修饰的Annotation的生命周期:SOURCE、CLASS、RUNTIME
  • Target:指定所修饰的Annotation能修饰哪些结构
  • Documented:指明所修饰的Annotation在执行javadoc命令之后能保留下来
  • Inherited:指明所修饰的Annotation具有继承性

5. 获取注解的信息

通过反射进行调用

前提:要求此注解的元注解Retention中声明的生命周期状态为RUNTIME

6. JDK8中注解的新特性

可重复注解、类型注解

  • 可重复注解
    • 在MyAnnotation上声明@Repeatable,程远志为MyAnnotations.class
    • MyAnnotation的@Target和@Retention等元注解和MyAnnotations相同
  • 类型注解:

    • ElementType.TYPE_PARAMETER表示该注解能写在类型变量的声明语句中(如:泛型声明)

    • ElementType.TYPE_USE表示该注解能写在使用类型的任何语句中

推荐阅读