2022-03-15 17:18

Java枚举

wanmatea

JavaEE

(1129)

(0)

收藏

1.枚举特性

1.1.枚举简介

enum的全称为 enumeration, 是 JDK 1.5 中引入的新特性。,通过关键字enum来定义枚举类。枚举类是一种特殊类,它和普通类一样可以使用构造器、定义成员变量和方法,也能实现一个或多个接口,但枚举类不能继承其他类。

所有的枚举类型隐性地继承自 java.lang.Enum。枚举实质上还是类!而每个被枚举的成员实质就是一个枚举类型的实例,他们默认都是public static final修饰的。可以直接通过枚举类型名使用它们。

在Java中,被 enum 关键字修饰的类型就是枚举类型。形式如下:

enum Color 
{ 
    RED, GREEN, BLUE
}

如果枚举不添加任何方法,枚举值默认为从0开始的有序数值。以 Color 枚举类型举例,它的枚举常量依次为 RED:0,GREEN:1,BLUE 2。

通过ordinal()方法来得到枚举所代表的值。

1.2.枚举原理

实际上,这个声明定义的类型是一个类,它刚好有四个实例,在此尽量不要构造新对象。

因此,在比较两个枚举类型的值时,不需要调用equals方法,而直接使用"=="就可以了。(equals()方法也是直接使用==,  两者是一样的效果)

Java Enum类型的语法结构尽管和java类的语法不一样,应该说差别比较大。但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum<E>。

image.png

1.3.枚举不能被继承

需要注意的是enum定义的类默认继承的是java.lang.Enum类而不是Object类。

同时注意枚举类不能派生子类(枚举类的默认修饰符为final)。其原因基于它仅仅有private构造器。那为什么要设计成这样呢?

事实上非常easy想明确,所谓枚举类就是有包括有固定数量实例(而且实例的值也固定)的特殊类,假设其含有public构造器,那么在类的外部就能够通过这个构造器来新建实例,显然这时实例的数量和值就不固定了,这与定义枚举类的初衷相矛盾,为了避免这样的形象。就对枚举类的构造器默认使用private修饰。假设为枚举类的构造器显式指定其他訪问控制符,则会编译出错。

另外。注意枚举类的全部实例必须在其首行显式列出,否则它不能产生实例。

1.4.使用场景

1、作为普通的常量使用,如 星期、季节、颜色、城市 等等;通常配合 switch 语句使用。     

2、往枚举中添加变量、构造函数、以达到灵活获取指定值的目的。      

3、通常用于一些业务系统中定义一些固定值,如用于匹配数据库中的字段值等。在平时数据库表的设计中,我们一般以数字来代表一些常量,那么在 java 中就可以通过枚举来将数据库字段的数值和所代表的常量对应起来。        

4、往枚举中添加自己特定方法,以实现自己所需的相关业务逻辑。

比如:可以通过状态码获得对应的状态码信息。

2.枚举的使用

2.1.Enum常用方法

方法

描述

ElementType[]  values()

按声明顺序返回包含此枚举类型的常量的数组

ElementType  valueOf(String name)  

返回带有指定名称的该类型的枚举常量

例如:Color color=Color.valueOf("RED");

可以把String类型转为Color类型。

<T extends Enum<T>>  T  valueOf(Class<T> enumType, String name)

返回带指定名称的指定枚举类型的枚举常量

int  compareTo(E o)

比较此枚举与指定对象的顺序

boolean  equals(Object other)

当指定对象等于此枚举常量时,返回 true

Class<E>  getDeclaringClass()

返回与此枚举常量的枚举类型相对应的 Class 对象

String  name()

返回此枚举常量的名称,在其枚举声明中对其进行声明

int  ordinal()

返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)


2.2.循环

public class Test {
    enum Color
    { 
        RED, GREEN, BLUE
    }
    public static void main(String[] args)
    {
        //循环输出
        for(Color c: Color.values())
        {
            System.out.println(c.ordinal()+" "+c);
         } 
      } 
}

输出结果:

0 RED

1 GREEN

2 BLUE

2.3.Switch

switch(Color.RED)
{
   case RED:
   System.out.println("RED");
   break;
   case GREEN:
   System.out.println("GREEN");
   break;
   case BLUE:
   System.out.println("BLUE");
   break;
}

输出结果:

RED

2.4.自定义方法

如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。

public class Test {
enum Color
{ 
    RED(1,"红色"), GREEN(2,"绿色"), BLUE(3,"蓝色");
    private String name ;
    private int index ;
    private Color(int index,String name){
    this.name = name ;
    this.index = index ;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getIndex() {
    return index;
}
public void setIndex(int index) {
    this.index = index;
}
}
public static void main(String[] args)
{
    //循环输出
    for(Color c: Color.values())
    {
    System.out.println(c.getIndex()+" "+c.getName());
}
}
}

输出结果:

1 红色

2 绿色

3 蓝色

2.5.实现接口

因为所有的枚举都继承自java.lang.Enum类。而Java不支持多继承,所以枚举对象不能再继承其他类。但是可以实现接口。

接口ColorInterface:

public interface ColorInterface {
    public String getColor();
}

枚举类Color:

public enum Color implements ColorInterface
{ 
                RED(1,"红色"), GREEN(2,"绿色"), BLUE(3,"蓝色"); //最后一个后面必须有分号
            private String name ;
        private int index ;
        private Color(int index,String name){
            this.name = name ;
            this.index = index ;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
           this.name = name;
        }
        public int getIndex() {
           return index;
        }
        public void setIndex(int index) {
           this.index = index;
        }
            @Override
        public String getColor() {
           return this.getName();
        }
}

测试:

public class Test {
    public static void main(String[] args)
    {
      System.out.println(Color.RED.getColor());
    }
}


0条评论

点击登录参与评论