nested enum-why is it used?

匿名 (未验证) 提交于 2019-12-03 03:08:02

问题:

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

回答1:

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.



回答2:

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.



回答3:

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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!