嵌套枚举-为什么使用它?

发布于 2024-10-12 15:18:47 字数 30 浏览 1 评论 0原文

我见过在枚举内声明枚举的构造。这是做什么用的?

I have seen constructs with an enum declared inside an enum. What is this used for ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

悍妇囚夫 2024-10-19 15:18:47

Java 中的枚举无法扩展,因此如果您想在一个地方整理强相关的枚举,您可以使用这些嵌套的枚举结构。例如:

public enum DepartmentsAndFaculties
{
   UN (null, "UN", "University"),
   EF (UN,   "EF", "Engineering Faculty"),
   CS (EF,   "CS", "Computer Science & Engineering"),
   EE (EF,   "EE", "Electrical Engineering");

   private final DepartmentsAndFaculties parent;
   private final String code, title;

   DepartmentsAndFaculties(DepartmentsAndFaculties parent, String code, String title)
   {
       this.parent = parent;
       this.code   = code;
       this.title  = title;
   }

   public DepartmentsAndFaculties getParent()
   {
       return parent;
   }

   public String getCode()
   {
       return code;
   }

   public String getTitle()
   {
       return title;
   }
}

这里,内部枚举由 {parent enum, code, title} 组合组成。用法示例:

 DepartmentsAndFaculties cs = DepartmentsAndFaculties.CS;
 cs.getTitle();

在构造分层实体/枚举时,您可以看到嵌套枚举的强大功能。

Enums in Java can't be extended, so if you wanna collate strongly-related enums in one place you can use these nested enum constructs. For example:

public enum DepartmentsAndFaculties
{
   UN (null, "UN", "University"),
   EF (UN,   "EF", "Engineering Faculty"),
   CS (EF,   "CS", "Computer Science & Engineering"),
   EE (EF,   "EE", "Electrical Engineering");

   private final DepartmentsAndFaculties parent;
   private final String code, title;

   DepartmentsAndFaculties(DepartmentsAndFaculties parent, String code, String title)
   {
       this.parent = parent;
       this.code   = code;
       this.title  = title;
   }

   public DepartmentsAndFaculties getParent()
   {
       return parent;
   }

   public String getCode()
   {
       return code;
   }

   public String getTitle()
   {
       return title;
   }
}

Here, inner enums consist of {parent enum, code, title} combinations. Example usage:

 DepartmentsAndFaculties cs = DepartmentsAndFaculties.CS;
 cs.getTitle();

You can see the power of nested enums when constructing hierarchical entities/enums.

虚拟世界 2024-10-19 15:18:47

您可能将枚举视为内部类型。当外部类型是类或接口时,最常见的是这种情况,但我认为没有任何理由不能使用枚举作为外部来完成此操作。

内部类型部分与代码组织有关。当您有几种相关的类型时,它们有助于避免创建一堆单独的文件。有时它可以使类型名称更直观。例如,请参见 Map 类及其内部 Entry 类。大多数对 Entry 的外部引用都会使用 Map.Entry 格式,这种格式非常可读。

使用内部类型的另一个原因是,如果外部类型是类或枚举,则内部类型可以是非公共的。这对于隐藏作为外部类型的实现细节的类型很有用。

You might mean an Enum as an inner type. This is most typically seen when the outer type is a class or an interface, but I suppose there isn't any reason this couldn't be done with enum as an outer.

Inner types are partly about code organization. They can be useful in avoiding creating a bunch of separate files when you have a few types that are related. Sometimes it can make type name more intuitive. For instance, see Map class and its inner Entry class. Most external references to Entry would use Map.Entry format, which is very readable.

The other reason for inner types is that if outer type is a class or an enum, then inner type can be non-public. This is useful for hiding types that are implementation details of the outer type.

别挽留 2024-10-19 15:18:47

我在极少数情况下使用了嵌套枚举,如果添加新名称会对操作或其他人产生影响,我想对枚举值强制执行命名约定。这是一个示例:

public enum MessageTemplateName {

    account_verify,
    vendor_job_request,
    account_job_confirmed,
    vendor_job_confirmed,
    account_friend_request,
    account_job_accepted,
    vendor_job_accepted_by_other;

    /** Make sure you tell operations if you're adding a new recipient */
    private enum Recipient { account, vendor }

    private Recipient recipient;
    private String messageName;

    MessageTemplateName () {
        final int firstUnderscore = name().indexOf('_');
        recipient = Recipient.valueOf(name().substring(0, firstUnderscore));
        messageName = name().substring(firstUnderscore+1);
    }

    public String getTemplateUrl (String baseUrl) {
        if (!baseUrl.endsWith("/")) baseUrl += "/";
        return baseUrl + recipient.name() + "/" + messageName + ".vm";
    }

}

我使用枚举是因为我希望能够在不同的地方传递通用的“消息模板名称”。正如您所看到的,枚举名称的第一部分对应于服务器上的目录,名称的其余部分指的是 Velocity 模板文件名。如果其他工程师开始引入新的常量,我想确保它们被归档在适当的“收件人”下,或者如果合法地需要创建新的收件人,那么这是有意识地这样做,并且您会通知操作(在生产中创建目录、放置任何监视/权限等)。

有一个不错的论点是,如果在某个时候你的枚举变得太复杂,你可以用类/类层次结构加上更简单的枚举来替换它。不确定我的界限在哪里,但我想上面的内容正在朝那个方向发展。

I have used nested enums in rare cases where I wanted to enforce a naming convention on the enum values, if additions of new names would have implications for operations or other folks. Here's one example:

public enum MessageTemplateName {

    account_verify,
    vendor_job_request,
    account_job_confirmed,
    vendor_job_confirmed,
    account_friend_request,
    account_job_accepted,
    vendor_job_accepted_by_other;

    /** Make sure you tell operations if you're adding a new recipient */
    private enum Recipient { account, vendor }

    private Recipient recipient;
    private String messageName;

    MessageTemplateName () {
        final int firstUnderscore = name().indexOf('_');
        recipient = Recipient.valueOf(name().substring(0, firstUnderscore));
        messageName = name().substring(firstUnderscore+1);
    }

    public String getTemplateUrl (String baseUrl) {
        if (!baseUrl.endsWith("/")) baseUrl += "/";
        return baseUrl + recipient.name() + "/" + messageName + ".vm";
    }

}

I'm using an Enum because I want to be able to pass around a generic "message template name" in various places. As you can see, the first part of the enum name corresponds to a directory on a server, and the remainder of the name refers to a Velocity template file name. If fellow engineers started introducing new constants, I'd want to make sure they were filed under the appropriate "recipient", or if a new recipient legitimately needs to be created, that it's a conscious effort to do so, and you'll inform operations (create the directory in production, put any monitoring/permissions in place, etc).

There's a decent argument that, if at some point your Enum becomes too complex, you can replace it with a class/class hierarchy coupled with a much simpler enum. Not sure where I draw the line, but I suppose the above is heading in that direction.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文