What are enums and why are they useful?

2018-12-31 09:52发布

Today I was browsing through some questions on this site and I found a mention of an enum being used in singleton pattern about purported thread safety benefits to such solution.

I have never used enums and I have been programing in Java for more than couple a years now. And apparently they changed a lot. Now they even do full blown support of OOP within themselves.

Now why and what for should I use enum in day to day programming?

标签: java enums
23条回答
刘海飞了
2楼-- · 2018-12-31 10:29

Use enums for TYPE SAFETY, this is a language feature so you will usually get:

  • Compiler support (immediately see type issues)
  • Tool support in IDEs (auto-completion in switch case ...)

Enums can have methods, constructors, you can even use enums inside enums and combine enums with interfaces.

Think of enums as types to replace a well defined set of int constants (which Java 'inherited' from C/C++).

The book Effective Java 2nd Edition has a whole chapter about them and goes into more details. Also see this Stack Overflow post.

查看更多
春风洒进眼中
3楼-- · 2018-12-31 10:29

In my experience I have seen Enum usage sometimes cause systems to be very difficult to change. If you are using an Enum for a set of domain-specific values that change frequently, and it has a lot of other classes and components that depend on it, you might want to consider not using an Enum.

For example, a trading system that uses an Enum for markets/exchanges. There are a lot of markets out there and it's almost certain that there will be a lot of sub-systems that need to access this list of markets. Every time you want a new market to be added to your system, or if you want to remove a market, it's possible that everything under the sun will have to be rebuilt and released.

A better example would be something like a product category type. Let's say your software manages inventory for a department store. There are a lot of product categories, and many reasons why this list of categories could change. Managers may want to stock a new product line, get rid of other product lines, and possibly reorganize the categories from time to time. If you have to rebuild and redeploy all of your systems simply because users want to add a product category, then you've taken something that should be simple and fast (adding a category) and made it very difficult and slow.

Bottom line, Enums are good if the data you are representing is very static over time and has a limited number of dependencies. But if the data changes a lot and has a lot of dependencies, then you need something dynamic that isn't checked at compile time (like a database table).

查看更多
永恒的永恒
4楼-- · 2018-12-31 10:30

You should always use enums when a variable (especially a method parameter) can only take one out of a small set of possible values. Examples would be things like type constants (contract status: "permanent", "temp", "apprentice"), or flags ("execute now", "defer execution").

If you use enums instead of integers (or String codes), you increase compile-time checking and avoid errors from passing in invalid constants, and you document which values are legal to use.

BTW, overuse of enums might mean that your methods do too much (it's often better to have several separate methods, rather than one method that takes several flags which modify what it does), but if you have to use flags or type codes, enums are the way to go.

As an example, which is better?

/** Counts number of foobangs.
 * @param type Type of foobangs to count. Can be 1=green foobangs,
 * 2=wrinkled foobangs, 3=sweet foobangs, 0=all types.
 * @return number of foobangs of type
 */
public int countFoobangs(int type)

versus

/** Types of foobangs. */
public enum FB_TYPE {
 GREEN, WRINKLED, SWEET, 
 /** special type for all types combined */
 ALL;
}

/** Counts number of foobangs.
 * @param type Type of foobangs to count
 * @return number of foobangs of type
 */
public int countFoobangs(FB_TYPE type)

A method call like:

int sweetFoobangCount = countFoobangs(3);

then becomes:

int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET);

In the second example, it's immediately clear which types are allowed, docs and implementation cannot go out of sync, and the compiler can enforce this. Also, an invalid call like

int sweetFoobangCount = countFoobangs(99);

is no longer possible.

查看更多
梦该遗忘
5楼-- · 2018-12-31 10:31

I would use enums as a useful mapping instrument, avoiding multiple if-else provided that some methods are implemented.

public enum Mapping {

    ONE("1"),
    TWO("2");

    private String label;

    private Mapping(String label){
        this.label = label;
    }

    public static Mapping by(String label) {

        for(Mapping m: values() {
            if(m.label.equals(label)) return m;
        }

        return null;
    }

}

So the method by(String label) allows you to get the Enumerated value by non-enumerated. Further, one can invent mapping between 2 enums. Could also try '1 to many' or 'many to many' in addition to 'one to one' default relation

In the end, enum is a Java class. So you can have main method inside it, which might be useful when needing to do some mapping operations on args right away.

查看更多
深知你不懂我心
6楼-- · 2018-12-31 10:32

What is an enum

  • enum is a keyword defined for Enumeration a new data type. Typesafe enumerations should be used liberally. In particular, they are a robust alternative to the simple String or int constants used in much older APIs to represent sets of related items.

Why to use enum

  • enums are implicitly final subclasses of java.lang.Enum
  • if an enum is a member of a class, it's implicitly static
  • new can never be used with an enum, even within the enum type itself
  • name and valueOf simply use the text of the enum constants, while toString may be overridden to provide any content, if desired
  • for enum constants, equals and == amount to the same thing, and can be used interchangeably
  • enum constants are implicitly public static final

Note

  • enums cannot extend any class.
  • An enum cannot be a superclass.
  • the order of appearance of enum constants is called their "natural order", and defines the order used by other items as well: compareTo, iteration order of values, EnumSet, EnumSet.range.
  • An enumeration can have constructors, static and instance blocks, variables, and methods but cannot have abstract methods.
查看更多
梦该遗忘
7楼-- · 2018-12-31 10:32

As for me to make the code readable in future the most useful aplyable case of enumeration is represented in next snippet:

public enum Items {
    MESSAGES, CHATS, CITY_ONLINE, FRIENDS, PROFILE, SETTINGS, PEOPLE_SEARCH, CREATE_CHAT
}

@Override
public boolean onCreateOptionsMenu(Menu menuPrm) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menuPrm);
    View itemChooserLcl;
    for (int i = 0; i < menuPrm.size(); i++) {
        MenuItem itemLcl  = menuPrm.getItem(i);
            itemChooserLcl = itemLcl.getActionView();
            if (itemChooserLcl != null) {
                 //here Im marking each View' tag by enume values:
                itemChooserLcl.setTag(Items.values()[i]);
                itemChooserLcl.setOnClickListener(drawerMenuListener);
            }
        }
    return true;
}
private View.OnClickListener drawerMenuListener=new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Items tagLcl= (Items) v.getTag();
        switch (tagLcl){
            case MESSAGES: ;
            break;
            case CHATS : ;
            break;
            case CITY_ONLINE : ;
            break;
            case FRIENDS : ;
            break;
            case  PROFILE: ;
            break;
            case  SETTINGS: ;
            break;
            case  PEOPLE_SEARCH: ;
            break;
            case  CREATE_CHAT: ;
            break;
        }
    }
};
查看更多
登录 后发表回答