简体   繁体   中英

What is the purpose of Enum class which was introduced in Java 5?

My suggestions:

1) either enum s exist only before compilation (like generics; but I've never heard anything about it whilst it's written everywhere that generics are being erased after compilation)

2) or Enum is a way to maintain backward compatibility in some way (but I don't see that way yet).

Any other suggestions? (btw, have you ever used it in your code?)

UPD: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Enum.html

In other words, there's a enum keyword and Enum class. They both appeared in Java 5. The question: why do we need both?

The second question: why Enum became a part of the API?

From the Java Tutorials :

You should use enum types any time you need to represent a fixed set of constants. That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile time—for example, the choices on a menu, command line flags, and so on.

Enums are extremely useful, and yes, I have used them plenty of times in my code.


Edit:

...there's a enum keyword and Enum class. They both appeared in Java 5. The question: why do we need both?

This question is analogous to asking "there's a class keyword and an Object class. Why do we need both?"

In both cases, the keywords are basically hints to the compiler; you could think of them as syntactic sugar that saves you keystrokes, and lets the compiler do less work (by not making it guess about what you're declaring).

See this q&a as well.

...have you ever used it in your code?

The answer is still "yes." In particular, Enum#valueOf() is a static method useful for parsing strings:

DayOfWeek d = Enum.valueOf(DayOfWeek.class, "TUESDAY");

but of course this works, too:

DayOfWeek d = DayOfWeek.valueOf("TUESDAY");

Enums exist to represent type-safe enumerations (much better than using int constants for the same thing).

If you're asking what the purpose of the Enum class itself is - it's to act as the superclass for the user-defined enum s. Each enum is compiled into a class that extends Enum with the appropriate generic parameter (ie itself).

Why is this done via syntactic sugar rather than simple subclassing? For one, it enforces the specific syntax that enums have (static instances forming the enum members). Another reason might be that the generic manipulations required to subclass Enum<E extends Enum<E>> would be very confusing to developers who had never seen any generics before. By hiding this complexity behind a new keyword, developers wouldn't have to decipher it themselves. Finally, the keyword implies that it's a special construct that shouldn't really be treated the same as a normal class.

In my humble opinion, the main thing enums are good for is type safety.

Suppose you have a function which can be called with some option that has a fixed set of possibilities. Say, "sale" or "return". A really bad solution would be to pass in a string, like:

public void doTransaction(String type)
{
  if (type.equals("sale"))
    ... do whatever ...
}

One big catch to this method is if someone were to try calling it with "Sale" or "sail". Unless the program verifies that only valid parameters are passed in, misspellings could give mysterious bugs.

So okay, many programmers created constants for this:

public final static int SALE=1, RETURN=2;
public void doTransaction(int type)
{
  if (type==SALE)
  ... do whatever ...
}

That's much better, but it still has problems. Suppose we have two parameters:

public final static int SALE=1, RETURN=2;
public final static int DOMESTIC=1, FOREIGN=2;
public void doTransaction(int type, int locale)
{
  if (type==SALE && locale==DOMESTIC)
  ... etc ...
}

Now someone gets confused and calls doTransaction(FOREIGN, SALE) . This will compile successfully, pass any validity tests within the program, and give totally incorrect results. Because if you didn't catch it, the parameters are in the wrong order.

Enums solve this problem. If instead you write

enum SaleType {SALE, RETURN};
enum Locale {DOMESTIC, FOREIGN};
public void doTransaction(SaleType type, Locale locale)
... etc ...

Now if someone tries to write, doTransaction(Locale.FOREIGN, SaleType.SALE) , they get a compile-time error, and immediately know that they have the parameters wrong.

Enum was added so the functionality provided by enum is visable and documented. What would be gained by hiding this class?

generics are not erased after compilation.

Not sure why an Enum class would be needed for backward compatibility.

I have used the class to read what Enums do and in code to check for Enum type, valueOf etc.

Ironically, this question was posted just before yours. It shows examples of using the class. Checking if a class is java.lang.Enum

either enums exist only before compilation

This is true, if you're talking about the enum syntax in the declaration, as opposed to the class syntax. At the bytecode level, Java enums are classes just like any other class. The enum semantics are basically implemented by the Java compiler.

在他们的Javadoc上查看完整的推理列表

I am not sure about #2. But I use Enums all the time in Java. Instead of doing

public static final int OPTION_ONE = 1;
public static final int OPTION_TWO = 2;

You can do

public enum Option{one, two}

This is much cleaner because now you can declare all your funcitons like so:

public void doSomething(Option o);

Where as the old way, you had to do public void doSomething(int i) and I could have passed any integer. Therefore, the parameter was never check to make sure it is a valid option. This allows for much cleaner code at compile time and run time.

I also use Enum a lot when it gets to doing variations of the same things. Let's say we have a sort attribute.

You can do something like this which is very clean and much BETTER than case statements.

public enum Sort {
        Everyone {
            @Override
            List<Checkin> refreshList(Client client, Location location) throws IOException {
                return client.checkins().getList();
            }
        },
        NearBy {
            @Override
            List<Checkin> refreshList(Client client, Location location) throws IOException {
                return client.checkinsNear(location.getLatitude(), location.getLongitude()).getList();
            }
        }; // and any other sorts

        abstract List<Checkin> refreshList(Client client, Location location) throws IOException;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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