关于enumjava的信息

发布时间:2023-01-08

本文目录一览:

  1. java中的enum有什么用呢?
  2. enum是java关键字吗?
  3. enum在java中是什么意思
  4. [Java 中 Enum 如何继承?](#Java 中 Enum 如何继承?)
  5. java的enum到底有什么用?

java中的enum有什么用呢?

enum也就是枚举,像一个集合,只不过集合里面的内容都固定了。

public enum Season3 {
    SPRING("春天"),
    SUMMER("夏天"),
    AUTUMN("秋天"),
    WINTER("冬天");
    private String name;
    private Season3(String name) {
        this.name = name;
    }
    public double getAvgTemp() {
        switch (this) {
            case SPRING:
                return 10.2;
            case SUMMER:
                return 25.8;
            case AUTUMN:
                return 19.6;
            case WINTER:
                return -3.6;
        }
        return 0.0;
    }
    public String getName() {
        return name;
    }
}
public class Test {
    public static void main(String[] args) {
        m3(Season3.SPRING);
    }
    public static void m3(Season3 season) {
        System.out.println(season.getName() + ":" + season.getAvgTemp());
        Season3[] allSeason = Season3.values(); // 返回枚举类中所有枚举值的一个数组
        System.out.println(allSeason[0]);
    }
}

enum是java关键字吗?

enum是Java的关键字,Java的关键字如下:

  • abstract:表明类或者成员方法具有抽象属性
  • assert:用来进行程序调试
  • boolean:基本数据类型之一,布尔类型
  • break:提前跳出一个块
  • byte:基本数据类型之一,字节类型
  • case:用在switch语句之中,表面其中的一个分支
  • catch:用在异常处理中,用来捕捉异常
  • char:基本数据类型之一,字符类型
  • class:类
  • const:保留关键字,没有具体含义
  • continue:回到一个块的开始处
  • default:默认,例如,用在switch语句中,表明一个默认的分支
  • do:用在do-while循环结构中
  • double:基本数据类型之一,双精度浮点数类型
  • else:用在条件语句中,表明当条件不成立时的分支
  • enum:枚举
  • extends:表明一个类型是另一个类型的子类型,这里常见的类型有类和接口
  • final:用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变
  • finally:用于处理异常情况,用来声明一个基本肯定会被执行到的语句块
  • float:基本数据类型之一,单精度浮点数类型
  • for:一种循环结构的引导词
  • goto:保留关键字,没有具体含义
  • if:条件语句的引导词
  • implements:表明一个类实现了给定的接口
  • import:表明要访问指定的类或包
  • instanceof:用来测试一个对象是否是指定类型的实例对象
  • int:基本数据类型之一,整数类型
  • interface:接口
  • long:基本数据类型之一,长整数类型
  • native:用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的
  • new:用来创建新实例对象
  • package:包
  • private:一种访问控制方式:私用模式
  • protected:一种访问控制方式:保护模式
  • public:一种访问控制方式:共用模式
  • return:从成员方法中返回数据
  • short:基本数据类型之一,短整数类型
  • static:表明具有静态属性
  • strictfp:用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范
  • super:表明当前对象的父类型的引用或者父类型的构造方法
  • switch:分支语句结构的引导词
  • synchronized:表明一段代码需要同步执行
  • this:指向当前实例对象的引用
  • throw:抛出一个异常
  • throws:声明在当前定义的成员方法中所有需要抛出的异常
  • transient:声明不用序列化的成员域
  • try:尝试一个可能抛出异常的程序块
  • void:声明当前成员方法没有返回值
  • volatile:表明两个或者多个变量必须同步地发生变化
  • while:用在循环结构中

enum在java中是什么意思

Enum 类型的介绍

枚举类型(Enumerated Type)很早就出现在编程语言中,它被用来将一组类似的值包含到一种类型当中。而这种枚举类型的名称则会被定义成独一无二的类型描述符,在这一点上和常量的定义相似。不过相比较常量类型,枚举类型可以为申明的变量提供更大的取值范围。 举个例子来说明一下,如果希望为彩虹描绘出七种颜色,你可以在 Java 程序中通过常量定义方式来实现。

清单 1. 常量定义

public static class RainbowColor {
    // 红橙黄绿青蓝紫七种颜色的常量定义
    public static final int RED = 0;
    public static final int ORANGE = 1;
    public static final int YELLOW = 2;
    public static final int GREEN = 3;
    public static final int CYAN = 4;
    public static final int BLUE = 5;
    public static final int PURPLE = 6;
}

使用的时候,你可以在程序中直接引用这些常量。但是,这种方式还是存在着一些问题。

类型不安全

由于颜色常量的对应值是整数形,所以程序执行过程中很有可能给颜色变量传入一个任意的整数值,导致出现错误。

没有命名空间

由于颜色常量只是类的属性,当你使用的时候不得不通过类来访问。

一致性差

因为整形枚举属于编译期常量,所以编译过程完成后,所有客户端和服务器端引用的地方,会直接将整数值写入。这样,当你修改旧的枚举整数值后或者增加新的枚举值后,所有引用地方代码都需要重新编译,否则运行时刻就会出现错误。

类型无指意性

由于颜色枚举值仅仅是一些无任何含义的整数值,如果在运行期调试时候,你就会发现日志中有很多魔术数字,但除了程序员本身,其他人很难明白其奥秘。

如何定义 Enum 类型

为了改进 Java 语言在这方面的不足弥补缺陷,5.0 版本 SDK 发布时候,在语言层面上增加了枚举类型。枚举类型的定义也非常的简单,用 enum 关键字加上名称和大括号包含起来的枚举值体即可,例如上面提到的彩虹颜色就可以用新的 enum 方式来重新定义:

enum RainbowColor { RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE }

从上面的定义形式来看,似乎 Java 中的枚举类型很简单,但实际上 Java 语言规范赋予枚举类型的功能非常的强大,它不仅是简单地将整形数值转换成对象,而是将枚举类型定义转变成一个完整功能的类定义。这种类型定义的扩展允许开发者给枚举类型增加任何方法和属性,也可以实现任意的接口。另外,Java 平台也为 Enum 类型提供了高质量的实现,比如默认实现 ComparableSerializable 接口,让开发者一般情况下不用关心这些细节。 回到本文的主题上来,引入枚举类型到底能够给我们开发带来什么样好处呢?一个最直接的益处就是扩大 switch 语句使用范围。5.0 之前,Java 中 switch 的值只能够是简单类型,比如 intbyteshortchar,有了枚举类型之后,就可以使用对象了。这样一来,程序的控制选择就变得更加的方便,看下面的例子:

清单 2. 定义 Enum 类型

// 定义一周七天的枚举类型
public enum WeekDayEnum { Mon, Tue, Wed, Thu, Fri, Sat, Sun }
// 读取当天的信息
WeekDayEnum today = readToday();
// 根据日期来选择进行活动
switch (today) {
    case Mon: do something; break;
    case Tue: do something; break;
    case Wed: do something; break;
    case Thu: do something; break;
    case Fri: do something; break;
    case Sat: play sports game; break;
    case Sun: have a rest; break;
}

对于这些枚举的日期,JVM 都会在运行期构造成出一个简单的对象实例一一对应。这些对象都有唯一的 identity,类似整形数值一样,switch 语句就根据此来进行执行跳转。

如何定制 Enum 类型

除了以上这种最常见的枚举定义形式外,如果需要给枚举类型增加一些复杂功能,也可以通过类似 class 的定义来给枚举进行定制。比如要给 enum 类型增加属性,可以像下面这样定义:

清单 3. 定制枚举类型

// 定义 RSS(Really Simple Syndication) 种子的枚举类型
public enum NewsRSSFeedEnum {
    // 雅虎头条新闻 RSS 种子
    YAHOO_TOP_STORIES(""),
    // CBS 头条新闻 RSS 种子
    CBS_TOP_STORIES(""),
    // 洛杉矶时报头条新闻 RSS 种子
    LATIMES_TOP_STORIES("");
    // 枚举对象的 RSS 地址的属性
    private String rss_url;
    // 枚举对象构造函数
    private NewsRSSFeedEnum(String rss) {
        this.rss_url = rss;
    }
    // 枚举对象获取 RSS 地址的方法
    public String getRssURL() {
        return this.rss_url;
    }
}

上面头条新闻的枚举类型增加了一个 RSS 地址的属性,记录头条新闻的访问地址。同时,需要外部传入 RSS 访问地址的值,因而需要定义一个构造函数来初始化此属性。另外,还需要向外提供方法来读取 RSS 地址。

如何避免错误使用 Enum

不过在使用 Enum 时候有几个地方需要注意:

  • enum 类型不支持 public 和 protected 修饰符的构造方法,因此构造函数一定要是 private 或 friendly 的。也正因为如此,所以枚举对象是无法在程序中通过直接调用其构造方法来初始化的。
  • 定义 enum 类型时候,如果是简单类型,那么最后一个枚举值后不用跟任何一个符号;但如果有定制方法,那么最后一个枚举值与后面代码要用分号 ';' 隔开,不能用逗号或空格。
  • 由于 enum 类型的值实际上是通过运行期构造出对象来表示的,所以在 cluster 环境下,每个虚拟机都会构造出一个同义的枚举对象。因而在做比较操作时候就需要注意,如果直接通过使用等号 (==) 操作符,这些看似一样的枚举值一定不相等,因为这不是同一个对象实例。 看下面的这个例子:

清单 4. 避免错误使用 Enum 示例

// 定义一个一周七天的枚举类型
package example.enumeration.codes;
public enum WeekDayEnum {
    Mon(1), Tue(2), Wed(3), Thu(4), Fri(5), Sat(6), Sun(7);
    private int index;
    WeekDayEnum(int idx) {
        this.index = idx;
    }
    public int getIndex() {
        return index;
    }
}
// 客户端程序,将一个枚举值通过网络传递给服务器端
package example.enumeration.codes;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class EnumerationClient {
    public static void main(String... args) throws UnknownHostException, IOException {
        Socket socket = new Socket();
        // 建立到服务器端的连接
        socket.connect(new InetSocketAddress("127.0.0.1", 8999));
        // 从连接中得到输出流
        OutputStream os = socket.getOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(os);
        // 将星期五这个枚举值传递给服务器端
        oos.writeObject(WeekDayEnum.Fri);
        oos.close();
        os.close();
        socket.close();
    }
}
// 服务器端程序,将从客户端收到的枚举值应用到逻辑处理中
package example.enumeration.codes;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class EnumerationServer {
    public static void main(String... args) throws IOException, ClassNotFoundException {
        ServerSocket server = new ServerSocket(8999);
        // 建立服务器端的网络连接侦听
        Socket socket = server.accept();
        // 从连接中获取输入流
        InputStream is = socket.getInputStream();
        ObjectInputStream ois = new ObjectInputStream(is);
        // 读出客户端传递来的枚举值
        WeekDayEnum day = (WeekDayEnum) ois.readObject();
        // 用值比较方式来对比枚举对象
        if (day == WeekDayEnum.Fri) {
            System.out.println("client Friday enum value is same as server's");
        } else if (day.equals(WeekDayEnum.Fri)) {
            System.out.println("client Friday enum value is equal to server's");
        } else {
            System.out.println("client Friday enum value is not same as server's");
        }
        // 用 switch 方式来比较枚举对象
        switch (day) {
            case Mon:
                System.out.println("Do Monday work");
                break;
            case Tue:
                System.out.println("Do Tuesday work");
                break;
            case Wed:
                System.out.println("Do Wednesday work");
                break;
            case Thu:
                System.out.println("Do Thursday work");
                break;
            case Fri:
                System.out.println("Do Friday work");
                break;
            case Sat:
                System.out.println("Do Saturday work");
                break;
            case Sun:
                System.out.println("Do Sunday work");
                break;
            default:
                System.out.println("I don't know which is day");
                break;
        }
        ois.close();
        is.close();
        socket.close();
    }
}

打印结果如下:

client Friday enum value is same as server's
Do Friday work

通过程序执行结果,我们能够发现在分布式条件下客户端和服务端的虚拟机上都生成了一个枚举对象,即使看起来一样的 Fri 枚举值,如果使用等号 == 进行比较的话会出现不等的情况。而 switch 语句则是通过 equals 方法来比较枚举对象的值,因此当你的枚举对象较复杂时候,你就需要小心 override 与比较相关的方法,防止出现值比较方面的错误。

Enum 相关工具类

JDK5.0 中在增加 Enum 类的同时,也增加了两个工具类 EnumSetEnumMap,这两个类都放在 java.util 包中。EnumSet 是一个针对枚举类型的高性能的 Set 接口实现。EnumSet 中装入的所有枚举对象都必须是同一种类型,在其内部,是通过 bit-vector 来实现,也就是通过一个 long 型数。EnumSet 支持在枚举类型的所有值的某个范围中进行迭代。回到上面日期枚举的例子上:

enum WeekDayEnum { Mon, Tue, Wed, Thu, Fri, Sat, Sun }

你能够在每周七天日期中进行迭代,EnumSet 类提供一个静态方法 range 让迭代很容易完成:

for (WeekDayEnum day : EnumSet.range(WeekDayEnum.Mon, WeekDayEnum.Fri)) {
    System.out.println(day);
}

打印结果如下:

Mon
Tue
Wed
Thu
Fri

EnumSet 还提供了很多个类型安全的获取子集的 of 方法,使你很容易取得子集:

EnumSet<WeekDayEnum> subset = EnumSet.of(WeekDayEnum.Mon, WeekDayEnum.Wed);
for (WeekDayEnum day : subset) {
    System.out.println(day);
}

打印结果如下:

Mon
Wed

EnumSet 类似,EnumMap 也是一个高性能的 Map 接口实现,用来管理使用枚举类型作为 keys 的映射表,内部是通过数组方式来实现。EnumMap 将丰富的和安全的 Map 接口与数组快速访问结合到一起,如果你希望要将一个枚举类型映射到一个值,你应该使用 EnumMap。看下面的例子:

清单 5. EnumMap 示例

// 定义一个 EnumMap 对象,映射表主键是日期枚举类型,值是颜色枚举类型
private static Map<WeekDayEnum, RainbowColor> schema =
        new EnumMap<WeekDayEnum, RainbowColor>(WeekDayEnum.class);
static {
    // 将一周的每一天与彩虹的某一种色彩映射起来
    for (int i = 0; i < WeekDayEnum.values().length; i++) {
        schema.put(WeekDayEnum.values()[i], RainbowColor.values()[i]);
    }
}
System.out.println("What is the lucky color today?");
System.out.println("It's " + schema.get(WeekDayEnum.Sat));

当你询问周六的幸运色彩时候,会得到蓝色:

清单 6. 运行结果

What is the lucky color today?
It's BLUE

结束语

Enum 类型提出给 JAVA 编程带来了极大的便利,让程序的控制更加的容易,也不容易出现错误。所以在遇到需要控制程序流程时候,可以多想想是否可以利用 enum 来实现。

Java 中 Enum 如何继承?

Java Enum 是不能继承的,以下是解释: 枚举类使用 enum 定义后在编译后默认继承了 java.lang.Enum 类,而不是普通的继承 Object 类。enum 声明类继承了 SerializableComparable 两个接口。且采用 enum 声明后,该类会被编译器加上 final 声明(同 String),故该类是无法继承的。枚举类的内部定义的枚举值就是该类的实例(且必须在第一行定义,当类初始化时,这些枚举值会被实例化)。 Java 5 新增的 enum 关键词,可以定义枚举类。该类是一个特殊的类,可以定义自己的 field、方法、可以实现接口,也可以定义自己的构造器。

java的enum到底有什么用?

1. 关于 Java Enum

Enum 一般用来表示一组相同类型的常量。如性别、日期、月份、颜色等。对这些属性用常量的好处是显而易见的,不仅可以保证单例,且比较时候可以用 == 来替换 equals。是一种好的习惯。JDK1.5 之前没有 Enum 这个类型,那时候一般用接口常量来替代。有了 Java Enum 之后,可以更贴近的表示这种常量。

2. 如何使用 Java Enum

简单的用法:Java Enum 简单的用法一般用于代表一组常用常量,可用来代表一类相同类型的常量值。如:

// 性别
public enum SexEnum {
    male, female;
}
// 颜色
public enum Color {
    RED, BLUE, GREEN, BLACK;
}

枚举对象里面的值都必须是唯一的。 可以通过 Enum 类型名直接引用该常量,如 SexEnum.male, Color.RED复杂用法:Java 为枚举类型提供了一些内置的方法,同时枚举常量还可以有自己的方法。可以很方便的遍历枚举对象,看个下面的例子:

WeekDay.java

/**
 * @author admin
 * 2015-12-03
 * 定义一个枚举类型,代表星期一到星期日的7个缩写常量
 * 同时还定义了枚举类型的属性day,该属性可以是final,也可是变量
 * 同时还定义了该枚举类型的一个方法printDay
 */
public enum WeekDay {
    Mon("Monday"), Tue("Tuesday"), Wed("Wednesday"), Thu("Thursday"),
    Fri("Friday"), Sat("Saturday"), Sun("Sunday");
    /**定义枚举类型自己的属性**/
    private final String day;
    private WeekDay(String day) {
        this.day = day;
    }
    /**定义枚举类型自己的方法**/
    public static void printDay(int i) {
        switch (i) {
            case 1: System.out.println(WeekDay.Mon); break;
            case 2: System.out.println(WeekDay.Tue); break;
            case 3: System.out.println(WeekDay.Wed); break;
            case 4: System.out.println(WeekDay.Thu); break;
            case 5: System.out.println(WeekDay.Fri); break;
            case 6: System.out.println(WeekDay.Sat); break;
            case 7: System.out.println(WeekDay.Sun); break;
            default: System.out.println("wrong number!");
        }
    }
    public String getDay() {
        return day;
    }
}

WeekDayTest.java

/**
 * @author admin
 * 2015-12-03
 * 测试枚举类型WeekDay.
 */
public class WeekDayTest {
    public static void main(String args[]) {
        for (WeekDay day : WeekDay.values()) {
            System.out.println(day + "====" + day.getDay());
        }
        WeekDay.printDay(5);
    }
}

输出结果为:

Mon====Monday
Tue====Tuesday
Wed====Wednesday
Thu====Thursday
Fri====Friday
Sat====Saturday
Sun====Sunday
Fri