简体   繁体   English

什么时候在 Java 中使用 Enum 类?

[英]When to use Enum class in java?

It may be very obvious questions, but is it good to use Enum class if you know that the list of values will keep increasing?这可能是非常明显的问题,但是如果您知道值列表会不断增加,是否可以使用 Enum 类?

Let's say you define an Event Enum first it contains only [Poo, Too] then as we know we always have some new requirement it becomes [Poo, Too, App, Laa] and that keep changing again and again,假设您首先定义了一个事件枚举,它只包含 [Poo, Too],然后我们知道我们总是有一些新的需求,它变成 [Poo, Too, App, Laa] 并且不断变化,

So what is the best approach in this case?那么在这种情况下最好的方法是什么?

tl;dr tl;博士

  • If the entire set of possible values is known at compile-time, use enum .如果在编译时已知整组可能值,请使用 enum
  • If values can be added or dropped while your system is in use (at runtime), then you cannot use an enum .如果可以在系统使用中(运行时)添加或删除值,则不能使用 enum Use a Set , List , or Map instead.请改用SetListMap

Known at compile-time编译时已知

An enum is appropriate when the domain (set of all possible values) is known at compile-time.当域(所有可能值的集合)在编译时已知时,枚举是合适的。

If this year your company is offering two products ( Poo & Too ), then make an enum for those two elements.如果今年您的公司提供两种产品( Poo 和 Too ),则为这两个元素进行枚举。

public enum Product { POO , TOO }

Next year, your company decides to grow their product offerings by adding App & Laa.明年,您的公司决定通过添加 App & Laa 来增加他们的产品供应。 As part of a planned deployment, add two more objects to your enum.作为计划部署的一部分,将另外两个对象添加到您的枚举中。

public enum Product { POO , TOO , APP , LAA }

By the way, notice the naming conventions.顺便说一下,请注意命名约定。 The enum has a regular class name (initial cap).枚举有一个常规的类名(初始上限)。 The objects being automatically instantiated are constants, and so are named in all-uppercase.被自动实例化的对象是常量,因此以全大写命名。

Also, be aware that the enum facility in Java is quite flexible and powerful, much more so than the usual naming-a-number enum scheme seen in most languages.另外,请注意 Java 中的枚举功能非常灵活和强大,比大多数语言中常见的命名数字枚举方案要强大得多。 You can have member variables and methods and constructors on a Java enum.您可以在 Java 枚举上拥有成员变量、方法和构造函数。 For example, you can add a getDisplayName method to provide text more appropriate to a user-interface than the all-caps object name, as seen in DayOfWeek::getDisplayName .例如,您可以添加一个getDisplayName方法来提供比全大写对象名称更适合用户界面的文本,如DayOfWeek::getDisplayName You can add quite a bit of functionality, such as ChronoUnit.between .您可以添加相当多的功能,例如ChronoUnit.between

What you cannot do at runtime with an enum in Java is add or remove objects.在运行时使用 Java 中的枚举不能做的是添加或删除对象。 Thus the requirement that you know your domain at compile-time.因此要求您在编译时了解您的域。 However, when working with a group of enum objects, you can use the highly-optimized EnumSet and EnumMap classes.但是,在处理一组枚举对象时,您可以使用高度优化的EnumSetEnumMap类。

Known at runtime运行时已知

If you cannot determine the domain at compile-time, if users can add or remove elements at runtime, then use a collection such as a List , Set , or Map rather than an enum.如果您不能确定在编译时域,如果用户可以添加或删除运行时的元素,然后使用一个集合,如ListSet ,或Map ,而不是一个枚举。


Singleton单身人士

Though not originally intended as a purpose of Enum in Java, an enum happens to be the safest (and simplest) way to implement the Singleton design pattern.虽然最初不是作为 Java 中Enum的目的,但 enum 恰好是实现单例设计模式的最安全(也是最简单)的方式。

This approach to a singleton is explained in the famous book Effective Java by Dr. Joshua Bloch, et al. Joshua Bloch 博士等人在著名的Effective Java一书中解释了这种处理单例的方法。 Using an enum solves multiple obscure technical problems with other approaches to a singleton.使用枚举可以通过其他方法解决单例的多个晦涩的技术问题。

Your question is pretty generic and I'm pretty sure there is no single right answer.你的问题很笼统,我很确定没有单一的正确答案。 But judging based on spring* tags, I suppose you might be asking about enums in DTOs that being sent over your system in serialized form.但是根据 spring* 标签判断,我想您可能会询问 DTO 中以序列化形式通过您的系统发送的枚举。 If that's the case, I would recommend to choose String in DTO, while inside single app it's ok to use enum .如果是这种情况,我建议在 DTO 中选择String ,而在单个应用程序中使用enum Then you would just care about deserialization/conversion in a factory manner, having ability to handle unknown/missing constant gracefully by logging/providing fallback or meaningful error.然后,您将只关心以工厂方式进行反序列化/转换,能够通过记录/提供回退或有意义的错误来优雅地处理未知/丢失的常量。

It depends on a case-by-case situation and your question doesn't have much context.这取决于具体情况,您的问题没有太多上下文。 However, I do recommend using ENUMs for many cases, including if you expect the list of ENUMs to increase.但是,我确实建议在许多情况下使用 ENUM,包括如果您希望 ENUM 列表增加。

Some reasons to use them are:使用它们的一些原因是:

  1. It creates a definite guide of ENUM elements that can be used throughout your code.它创建了可在整个代码中使用的 ENUM 元素的明确指南。 It eliminates uncertainty over what something is named or what it is.它消除了对某物的名称或它是什么的不确定性。 For example ENUM that contains list of animals, or enum of "something".例如包含动物列表的 ENUM,或“某物”的枚举。
  2. Its easy to refactor later if you need to change anything.如果您需要更改任何内容,以后很容易重构。

I'm sure there are many more reasons, I find it like a table of contents sometimes.我敢肯定还有更多原因,有时我觉得它就像一个目录。 For many cases, you can completely avoid it and be fine but I think its better to use it in general if you're on the fence.在许多情况下,您可以完全避免它并且很好,但我认为如果您处于围栏状态,通常最好使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM