ITPub博客

首页 > 应用开发 > Java > 深入浅出 Java 中枚举的实现原理

深入浅出 Java 中枚举的实现原理

原创 Java 作者:恒生LIGHT云社区 时间:2021-12-14 13:32:31 0 删除 编辑

作者:幻好

来源: 恒生LIGHT云社区

Java 中的枚举— Enum 的全称为 Enumeration, 在 JDK 1.5 时就引入的特性,通过 java.lang 包中调用。

基本概述

在 JDK1.5 之前,通过定义常量使用的都是: public static fianl 。而枚举的设计,就是把相关的常量分组到一个枚举类型里,方便创建和管理。

比如我们要定义一个颜色常量:


public 
enum 
Colour {

    RED,  YELLOW,  BLUE,  GREEN
}

这段代码通过底层编译后,实际创建了4个枚举对象:


new 
Enum
<
EnumTest
>(
"RED", 
0);

new  Enum < EnumTest >( "YELLOW",  1);
new  Enum < EnumTest >( "BLUE",  2);
new  Enum < EnumTest >( "GREEN",  3);

使用方式

条件选择

enum 能通过 switch 方法进行简单条件判断


Colour 
color 
= 
Colour.
RED;

switch ( color) {
    case  RED:
        System. out. println( "红色");
        break;
    case  YELLOW:
        System. out. println( "黄色");
        break;
    case  GREEN:
        System. out. println( "绿色");
        break;
    case  BLUE:
        System. out. println( "蓝色");
        break;
    default:
        System. out. println( color);
        break;
}

循环遍历

通过循环遍历 .values() 能够取到对象中的值


for (
Colour 
e : 
Colour.
values()) {

    System. out. println( e. toString());
}

集合映射

在我们使用枚举类型作为集合的类型或映射中的键的类型时,可以使用专门且高效的集合和映射实现。如: java.util.EnumSet 、 java.util.EnumMap


// EnumSet的使用

EnumSet < Colour >  colorSet  =  EnumSet. allOf( Colour. class);
for ( Colour  color :  colorSet) {
    System. out. println( color);
}

// EnumMap的使用
EnumMap < Colour,  String >  colorMap  =  new  EnumMap( Colour. class);
colorMap. put( Colour. RED,  "红色");
colorMap. put( Colour. YELLOW,  "黄色");
colorMap. put( Colour. GREEN,  "绿色");
colorMap. put( Colour. BLUE,  "蓝色");

Set < Map. Entry < Colour,  String >>  colorEntries  =  colorMap. entrySet();
for ( Map. Entry < Colour,  String >  entry :  colorEntries) {
    System. out. println( entry. getKey(). name()  +  ":"  +  entry. getValue());
}

常用方法

通过   java.lang.Enum 类的源码,可以探索下枚举常用的一些方法和设计思想:

public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
// Enum 唯一的构造函数,由于 protected 修饰,所以不能调用这个构造函数。 它供编译器为响应枚举类型声明而发出的代码使用。

protected Enum(String name, int ordinal) {
  this.name = name;
  this.ordinal = ordinal;
}
```
// 返回此枚举常量的名称,与在其枚举声明中声明的完全相同。
public final String name() {
  return name;
}
```
// 返回此枚举常量的序数(它在枚举声明中的位置,其中初始常量被分配零序数)。(但大多数程序员不会使用这种方法)
public final int ordinal() {
  return ordinal;
}
```
// 与指定的对象进行比较以进行排序,当此对象小于、等于或大于指定对象时,返回一个负整数、零或正整数。且只能与相同枚举类型的其他枚举常量进行比较。 
public final int compareTo(E o) {
  Enum<?> other = (Enum<?>)o;
  Enum<E> self = this;
  if (self.getClass() != other.getClass() 
      self.getDeclaringClass() != other.getDeclaringClass())
      throw new ClassCastException();
  return self.ordinal - other.ordinal;
}
```
// 返回与此枚举常量的枚举类型对应的 Class 对象。
public final Class<E> getDeclaringClass() {
  Class<?> clazz = getClass();
  Class<?> zuper = clazz.getSuperclass();
  return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
}
```

}




## 底层原理

`enum` 的语法结构可能对于正常的 Java 看起来怪怪的,但是通过编译器编译后产生的是一个 `.class` 文件, 可以理解枚举的语法结构是一种规范,使编译器能识别并转化为相应的类,底层实际上还是 `class` 。

```java
public class com.project.demo.Colour extends java.lang.Enum{
  public static final com.project.demo.Colour RED;
  public static final com.project.demo.Colour YELLOW;
  public static final com.project.demo.Colour BLUE;
  public static final com.project.demo.Colour GREEN;
  static {};
}

总结

所以 enum 实际上在 Java 只是一个类的形式存在,它能够更加方便的帮助我们定义常量对象,并且支持定义属性和方法,在一定程度上提高了我们的编程效率。

但是在使用时需要注意, enum 不能支持继承,应该它已经继承了包里的 java.lang.Enum 类,所以在程序设计时我们需要考虑到。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70001864/viewspace-2847631/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2021-06-09

  • 博文量
    135
  • 访问量
    93930