Java enum枚举是怎么回事

Java1.5之前是没有枚举的,如果想使用类似枚举的特性,也即是需要使用常量的时候,可以通过如下代码完成:

Java中的常量定义:

publicclassSex2 {

publicstaticfinalintGIRL
= 1;

publicstaticfinalintBOY
= 2;

publicstaticvoid main(String[]args)
{

System.out.println(Sex2.GIRL);

}

}

但是这样做有个缺点,就是不够直观,我们打印出Sex2.GIRL,看到的却是数字1。于是我们有了下面的改进:

改进一:

publicclassSex3 {

publicstaticfinal StringGIRL
="GIRL";

publicstaticfinal StringBOY
="BOY";

publicstaticvoid main(String[]args)
{

System.out.println(Sex3.GIRL);

}

}

现在就比较直观了,我们打印出Sex3.GIRL,就能看到是GIRL,意思十分明确。可是问题又来了,如果我有一个方法接受GIRL或BOY为参数,但是我不能保证别人调用方法时使用别的字符串,比如“KID”。于是我们又有了进一步的改进:

改进二:

publicclassSex4 {

publicstaticfinal Sex4GIRL
=new Sex4("GIRL");

publicstaticfinal Sex4BOY
=new Sex4("GIRL");

private Stringsex;

private Sex4(Stringsex){

this.sex =sex;

}

public String toString(){

returnsex;

}

}

这样在需要使用性别的地方,就可以通过使用Sex4这个类型来保证性别时能是BOY或者GIRL了。比如类似如下函数的定义:

publicvoidoutSex(Sex4sex){

System.out.println(sex);

}

但是现在问题又来了,我们只是要使用两个常量,但是却要写那么多行代码(定义Sex4的时候),有没有简单的做法呢?答案当然是有,为了简化我们的代码书写,Java enum类型横空出世,下面的代码跟上面Sex4的定义是等效的:

改进三,enum类型横空出世:

publicenumSexEnum {

GIRL,

BOY

}

我的天!简直不敢相信,真是太简洁了!那需要使用他的地方该如何定义呢:

publicvoidoutSex(SexEnumsex){

System.out.println(sex);

}

疑问:既然Java1.5之前没有enum,那么1.5多出来的enum到底是什么东西?他跟一个普通的类有什么不同呢?

告诉你吧,实际上Java 中的enum就是就是类,定义了一个enum就是定义了一个类,对SexEnum.class的反编译印证了这一点。

javap -p SexEnum.class

Compiled from "SexEnum.java"

public final class SexEnum extendsjava.lang.Enum<SexEnum> {

public static final SexEnum GIRL;

public static final SexEnum BOY;

private static final SexEnum[] $VALUES;

public static SexEnum[] values();

public static SexEnum valueOf(java.lang.String);

private SexEnum();

static {};

}

我们看到SexEnum是一个被final修饰的类,继承自java.lang.Enum。还看到除了我们自己定义的GIRL和BOY成员之外,类里面还多了四个成员和一个静态代码块。请注意构造方法是私有的!你可能已经猜到了,这里的继承关系,及这些成员是编译器帮我们加上的。通过反编译可以看到这些成员函数以及静态代码块对应的JVM字节码:

javap -c SexEnum.class

Compiled from "SexEnum.java"

public final class SexEnum extendsjava.lang.Enum<SexEnum> {

public static final SexEnum GIRL;

public static final SexEnum BOY;

public static SexEnum[] values();

Code:

0: getstatic     #1                  // Field $VALUES:[LSexEnum;

3: invokevirtual #2                 // Method "[LSexEnum;".clone:()Ljava/lang/Object;

6: checkcast     #3                  // class"[LSexEnum;"

9: areturn

public static SexEnum valueOf(java.lang.String);

Code:

0: ldc           #4                  // class SexEnum

2: aload_0

3: invokestatic  #5                  // Methodjava/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;

6: checkcast     #4                  // class SexEnum

9: areturn

static {};

Code:

0: new           #4                  // class SexEnum

3: dup

4: ldc           #7                  // String GIRL

6: iconst_0

7: invokespecial #8                 // Method "<init>":(Ljava/lang/String;I)V

10: putstatic     #9                  // Field GIRL:LSexEnum;

13: new           #4                  // class SexEnum

16: dup

17: ldc           #10                 // String BOY

19: iconst_1

20: invokespecial #8                 // Method "<init>":(Ljava/lang/String;I)V

23: putstatic     #11                 // Field BOY:LSexEnum;

26: iconst_2

27: anewarray     #4                  // class SexEnum

30: dup

31: iconst_0

32: getstatic     #9                  // Field GIRL:LSexEnum;

35: aastore

36: dup

37: iconst_1

38: getstatic     #11                 // Field BOY:LSexEnum;

41: aastore

42: putstatic     #1                  // Field $VALUES:[LSexEnum;

45: return

}

很明显,静态代码块对应的代码完成了对成员GIRL和BOY的初始化工作。好久没有看过JVM字节码,都忘光了,想明白上字节码的语义,请自行阅读《Java虚拟机说明书》

结论:通过定义枚举,可以保证需要使用该枚举的地方,参数一定是该枚举的成员,同时增强代码的可读性。enum不过是Java语言为我们提供的一个语法糖[1](什么是语法糖?),方便我们定义常量。通过enum关键字定义的实际上是一个类,只不过编译器会保证这个类继承自Enum,并且会给这个类自动的加入一些成员。

[1] 语法糖:就是在编译器层面对Java语法的改动,并没有改动JVM,即字节码的结构并没有改变。Java中的语法糖还有:泛型,增强的for等。

个人的浅薄理解,欢迎转载,转载注明出处http://blog.csdn.net/u014495327/article/details/42043823。by hoolee。

时间: 2024-08-25 00:04:57

Java enum枚举是怎么回事的相关文章

Java Enum枚举

1.代码 import java.lang.*; // enum showing Mobile prices enum Mobile { Samsung(400), Nokia(250),Motorola(325); int price; Mobile(int p) { price = p; } int showPrice() { return price; } } public class EnumDemo { public static void main(String args[]) {

Java enum枚举类型

java的枚举类型详解: 简单示例: public enum Color{ RED,BLUE,BLACK,YELLOW,GREEN } 复杂示例(带自定义构造方法与类型) public enum EnumTest { FRANK("The given name of me"), LIU("The family name of me"); private String context; private String getContext(){ return this.

Java enum 枚举还可以这么用

在大部分编程语言中,枚举类型都会是一种常用而又必不可少的数据类型,Java中当然也不会例外.然而,Java中的Enum枚举类型却有着许多你意想不到的用法,下面让我们一起来看看. 1.可以在enum中添加变量和方法 先来看一段代码示例: public enum State { Normal("正常态", 1), Update("已更新", 2), Deleted("已删除", 3), Fired("已屏蔽", 4); // 成员

Java Enum枚举 遍历判断 四种方式(包括 Lambda 表达式过滤)

package com.miracle.luna.lambda; import java.util.Arrays; /** * @Author Miracle Luna * @Date 2019/6/9 23:40 * @Version 1.0 */ public enum AlarmGrade { ATTENTION("attention", "提示"), WARNING("warning","警告"), SERIOUS(&

Java enum(枚举)的用法详解(转)

用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. public enum Color { RED, GREEN, BLANK, YELLOW } 用法二:switch JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强. enum Signal { GREEN, YELLOW, RED } pu

java Enum 枚举

看了点东西,发现对java枚举不是很了解,然后就找找看看记记了. 为什么要用枚举呢?枚举再jdk1.5之前是没有的,1.5之后java才支持枚举.为什么要用枚举呢? 如果一个变量只有几种可能的值,这时候我们可以用int.String或者其他类型的变量来表示,虽然可以这样做但是,这样我们无法保证 使用时候的值一定是我们约定好几个值,这样就难免产生不必要的麻烦,而枚举就能避免这样的错误,枚举类型其实就是将变量的值一一列举出来, 变量的值只限于列举出来的值的范围内,一旦定义了枚举类型变量,那么该变量只

java enum(枚举)使用详解 + 总结

enum 的全称为 enumeration, 是 JDK 1.5  中引入的新特性,存放在 java.lang 包中. 下面是我在使用 enum 过程中的一些经验和总结,主要包括如下内容: 1. 原始的接口定义常量 2. 语法(定义) 3. 遍历.switch 等常用操作 4. enum 对象的常用方法介绍 5. 给 enum 自定义属性和方法 6. EnumSet,EnumMap 的应用 7. enum 的原理分析 8. 总结 原始的接口定义常量 ? public interface ICon

Java enum枚举的用法

一. 出现背景: 在JDK1.5之前,我们定义常量是这样的:public static final String RED = "RED"; 在JDK1.5中加入了枚举类型,我们可以把相关的常量分组到一个枚举类中: public enum Color { RED, GREEN, BLUE; } 使用的时候可以这样:Color c = Color.RED 二. 枚举特点: 1. 枚举enum是一个特殊的Java类,它继承自java.lang.Enum,继承了很多Enum的方法.但枚举类是一

Java enum枚举的使用方法

一. 出现背景: 在JDK1.5之前,我们定义常量是这种:public static final String RED = "RED"; 在JDK1.5中增加了枚举类型,我们能够把相关的常量分组到一个枚举类中: public enum Color { RED, GREEN, BLUE; } 使用的时候能够这样:Color c = Color.RED 二. 枚举特点: 1. 枚举enum是一个特殊的Java类.它继承自java.lang.Enum,继承了非常多Enum的方法.但枚举类是一