Java hidden box operation-enum and hidden box operation enum
Enum, which is an enumeration type, has a similar type in each programming language.
Because it is rarely used, every time I see enum, it will be daunting, because its syntax is really "not playing as usual!
The general enum syntax is as follows:
Public class MyClass {private enum Fruit {APPLE, ORANGE, GRAPE, BANANA} // type definition private Fruit fruit = Fruit. APPLE; // type use private void useEnum () {if (fruit = Fruit. ORANGE) {System. out. println ("this is orange ");}}}
In the "Type Definition" section above, it is found that the statement defining an enum type is very different from the general Java syntax, in a class, variables, functions, and internal classes are generally defined, but this sentence does not feel like anything.
For enum, including similar enumeration types in C ++, I used to use rote memorization to treat it differently from other syntaxes. However, it is not used because the enumeration type is "unusual" and rarely used, and the specific syntax format will soon be forgotten.
Two days ago, when I read objective Java, I found a chapter dedicated to enum, and the benefits of calling enum in the book, and the advantages of enum in Java compared to enumeration types in other languages. I have a close understanding, but I began to pay attention to enum.
Through research from various aspects, I found that enum is unknown, as well as various dark box operations.
First, give the most important points:Enum is actually a class!
With this logic, the basic syntax of enum is half understood. How can I change the above "enum" to "class? For example, what is the problem with braces on both sides of the enumerated values? Is it clear?
Since enum is a class, I call it the Fruit class ?) Definition in another form
Public class MyClass {private class Fruit {// replace enum with the new definition private Fruit () {}// new Fruit public static final Fruit APPLE = new Fruit (); public static final Fruit ORANGE = new Fruit (); public static final Fruit GRAPE = new Fruit (); public static final Fruit BANANA = new Fruit ();} private Fruit fruit = Fruit. APPLE; // type use private void useEnum () {if (fruit = Fruit. ORANGE) {System. out. println ("this is orange ");}}}
After reading the code written with the regular class after the conversion, do you want to scream: Isn't this code with the same effect!
Yes, this is the hidden box operation of the compiler. When the compiler sees the enum keyword, it will naturally try to convert it to this. Each enumerated value is not an int value starting from 0 in C ++, but a class instance. And because of the final keyword, do you know why the enumerated values are in uppercase? Why does the static call form such as "Fruit. APPLE" be written because the static keyword is added?
This is not complete yet. The above is just the principle defined in enum. How can I traverse enum during actual use? How to output the int value represented by each enumerated value? How do I output the literal string values of each enumerated value?
In fact, the Fruit class given above is incomplete. The class that replaces enum inherits from java. lang. enum is an abstract class. When the compiler encounters enum, it automatically converts it to the corresponding operation in the Enum parent class.
// Enum class definition public abstract class Enum <E extends Enum <E> implements Serializable, Comparable <E> {...}
For example, the above Fruit class is actually like this.
private class Fruit extends java.lang.Enum { ....}
Let's take a look at the main members in Enum.
// This is only two member variables of the Enum class, for example, {APPLE, ORANGE, GRAPE}. The three enumerated values are actually instances of the subclass of The Enum class, And the names are respectively "APPLE ", "ORANGE", "GRAPE", ordinal are 0, 1, 2 private final String name; // literal String representation of enumeration values, such as "APPLE", "ORANGE ", private final int ordinal; // int value represented by the enumerated value, which is similar to the enumerated type in C ++. It can be understood as an index. The first value is 0 in the defined order, the second is 1, and so on.
You can obtain these two attribute values by using the get method.
// Obtain the literal value public final String name () {return name;} // obtain the index value public final int ordinal () {return ordinal ;}
In addition, when the enumerated value is output, the literal string value of the enumerated value is output, because the toString () method is called.
@Override public String toString() { return name; }
The Enum class implements the Comparable interface, so you can compare the enumerated values. In fact, it is the index value comparison.
// Returns the index value difference between two enumerated values: public final int compareTo (E o) {return ordinal-(Enum <?>) O). ordinal ;}
There are also two operations for enum, which should be implemented by the compiler by calling other methods of the Enum class.
The first is the enum values () method, which returns an array composed of all class instances, such as enum Fruit {APPLE, ORANGE, GRAPE}, and returns new Fruit [] {Fruit. APPLE, Fruit. ORANGE, Fruit. GRAPE}, which can be used for traversal operations.
for (Fruit f :Fruit.values()) { ....}
The second is when the switch is used for selection, you only need to write the enumeration value after the case, without having to write the class name.
Fruit f = Fruit. APPLE; switch (f) {case (APPLE) {// you do not have to or cannot write it as case (Fruit. APPLE), the compiler automatically determines this is an instance of the Fruit class... break;} case (ORANGE ){... break;} default {...}}
It is not clear how this is implemented, that is, the hidden box operations of the compiler itself.
In addition, the more advanced one is to regard enum as a class completely, so you can rewrite your own method and add your own member variables. For example, you can use enumeration values to implement four arithmetic operations:
Public enum Operation {// each enumeration value, that is, the Operation instance, actually defines an anonymous class during the Declaration and inherits the Operation class, the apply method PLUS {double apply (double x, double y) {return x + y ;}, MINUS {double apply (double x, double y) {return x-y ;}, TIMES {double apply (double x, double y) {return x * y ;}}, DIVIDE {double apply (double x, double y) {return x/y; }}; abstract double apply (double x, double y); // The abstract method defined in the Operation class}
The above code is actually translated
Public class Operation extends Enum {public static final Operation PLUS = new Operation () {// anonymous internal class @ Override double apply (double x, double y) {return x + y ;}};...... abstract double apply (double x, double y); // abstract method defined in the Operation class}
Of course, you can also implement enum by yourself, add member variables, and overload constructors.
Public enum Operation {PLUS ("+"), // equal to: public static final Operation PLUS = new Operation ("+"); MINUS ("-"), TIMES ("*"), DIVIDE ("/"); private final String symbol; // The self-added member variable Operation (String symbol) {this. symbol = symbol;} // constructor. parameters can be given in parentheses during column enumeration values. It is best not to write the access permission as public @ Override public String toString () {return symbol;} // rewrite the toString () method of the Enum class}
Finally, there is a small detail that should be noted that enumeration values are separated by commas. If the enum definition only contains enumeration values and there is nothing else, the enumerated value can end with ";". However, there are other definitions. For example, if there is another member method, you must first write out the enumerated values, add other definitions, and add ";" to the enumerated values.
Private enum Haha {private void f () {System. out. println ("!!!!!!!!! ") ;}; FACE, SUGAR, APPLE; // The enumerated value must be written first}
A major use of enumeration values is to replace the scattered definition of constants (public static final xxx xx = XX;), and these constants are only used for identifiers, and do not care about the number of constant values. After the enum definition is used, you can check the type. When there are many constants, you can also classify them and output the nominal value of the identifier.