In the previous series, we introduced the basic data types, classes, and interfaces in Java that represent and manipulate data, and this section explores the enumeration types in Java.
The so-called enumeration, is a special kind of data, its value is limited, can be enumerated, for example, a year is four seasons, a week has seven days, although the use of classes can also handle this data, but the enumeration type is more concise, safe and convenient.
Let's introduce the use of enumerations, and introduce their implementation principles.
Basis
Basic usage
Defining and using basic enumerations is relatively straightforward, let's take a look at an example, for the size of the clothes, we define an enumeration type size, which includes three sizes, small/medium/large, the code is as follows:
Public enum Size { SMALL, MEDIUM, LARGE}
Enumerations are defined using the enum keyword, where size consists of three values, representing small, medium, and large values, usually uppercase letters, and multiple values separated by commas. An enumeration type can be defined as a separate file, or it can be defined inside other classes.
You can use size like this:
Size size = Size.medium
Size size declares a variable size, whose type is size, Size=size.medium theenumeration value medium to the size variable.
The ToString method of the enumeration variable returns its literal value, and all enum types also have a name () method, which returns the same values as ToString (), for example:
Size size = Size.small; System.out.println (Size.tostring ()); System.out.println (Size.name ());
The output is small.
Enumeration variables can be compared using equals and =, and the result is the same, for example:
Size size = Size.small; System.out.println (Size= =Size.small); System.out.println (Size.equals (Size.small)); System.out.println (size==size.medium);
The output of the above code is three lines, true, True, false, respectively.
Enumeration values are sequential and can be compared in size. Enumeration types have a method int ordinal (), which represents the order in which the enumeration values are declared, starting with 0, for example, the following code output is 1:
Size size = size.medium; System.out.println (Size.ordinal ());
In addition, the enumeration type implements the Java API comparable interface, all can be compared with other enumeration values through the method CompareTo, comparison is actually the size of the comparison ordinal, for example, the following code output is 1, indicating that small is less than medium:
Size size = Size.small; System.out.println (Size.compareto (Size.medium));
Enumeration variables can be used in places like other types of variables, such as method parameters, class variables, instance variables, and so on, which can also be used with a switch statement, as shown in the code below:
static void Onchosen (size size) { switch (size) { case SMALL:System.out.printl N ( "Chosen small"); break case MEDIUM:System.out.println ( "Chosen Medium"); break case LARGE:System.out.println ( "Chosen large"); break
Inside a switch statement, the enumeration value cannot be prefixed with an enumeration type, for example, using SMALL directly, and cannot use Size.small.
The enumeration type has a static valueof (string) method that returns the enumeration value corresponding to the string, for example, the following code outputs true:
System.out.println (size.small==size.valueof ("SMALL"));
Enumeration types also have a static values method that returns an array that includes all the enumeration values, in the same order as they were declared, for example:
for (Size size:Size.values ()) { System.out.println (size);}
The screen output is three lines, respectively small, MEDIUM, LARGE.
Benefits of enumerations
Java is only supported for enumerations from JDK 5, and before that, it is common to define static shaping variables in a class to implement similar functionality, as shown in the code below:
class Size { publicstaticfinalint SMALL = 0; Public Static Final int MEDIUM = 1; Public Static Final int LARGE = 2;}
The benefits of enumerations are more obvious:
- The syntax for defining enumerations is more concise.
- Enumeration is more secure, a variable of an enumerated type, whose value is either null, or one of the enumeration values, and cannot be a different value, but with an shaping variable, its value is not enforced and the value may be invalid.
- The enumeration type comes with many convenient methods (such as values, ValueOf, tostring, etc.) that are easy to use.
Basic implementation Principles
The enumeration type is actually converted to a corresponding class by the Java compiler, which inherits the Java.lang.Enum class from the Java API.
The enum class has two instance variables name and ordinal, which need to be passed in the constructor method, name (), toString (), ordinal (), CompareTo (), Equals () Methods are implemented by the Enum class based on its instance variable name and ordinal.
The values and valueof methods are automatically added by the compiler to each enumeration type, and the code for the above enumerated type, size, is probably as follows:
Public Final classSizeextendsEnum<size> { Public Static FinalSize SMALL =NewSize ("SMALL", 0); Public Static FinalSize MEDIUM =NewSize ("MEDIUM", 1); Public Static FinalSize LARGE =NewSize ("LARGE", 2); Private Staticsize[] VALUES =NewSize[]{small,medium,large}; PrivateSize (String name,intordinal) { Super(name, ordinal); } Public Staticsize[] VALUES () {size[] values=NewSize[values.length]; System.arraycopy (VALUES,0, values,0, values.length); returnvalues; } Public StaticSize valueOf (String name) {returnEnum.valueof (Size.class, name); }}
Explain the points:
- The Size is final and cannot be inherited,enum<size> indicates that the parent class,,<size>, is generic and is described in the following article, which can be ignored here.
- The size has a private constructor that accepts name and ordinal, passed to the parent class, and private means that new instances cannot be created externally.
- The three enumeration values are actually three static variables and are final and cannot be modified.
- The values method is added by the compiler and has an internal values array that holds all the enumeration values.
- The valueof method calls the method of the parent class, with an extra pass of the parameter Size.class, which represents the type information of the class, the type information we introduce in the following article, the parent class is actually going back to call the values method, and the corresponding enumeration value is obtained according to the name comparison.
The generic enumeration variable is converted to the corresponding class variable, and in the switch statement, the enumeration value is converted to its corresponding ordinal value.
As you can see, the enumeration type is essentially a class, but because the compiler does a lot of things automatically, its use is more concise, secure, and convenient.
Typical scenario
Usage
The above enumeration usage is the simplest, the actual enumeration will often have associated instance variables and methods, for example, the size example above, each enumeration value may have associated abbreviations and Chinese names, may require a static method to return the corresponding enumeration value according to the abbreviation, the modified size code is as follows:
Public enumSize {SMALL ("S", "trumpet"), MEDIUM ("M", "Medium"), LARGE ("L", "large"); PrivateString abbr; PrivateString title; PrivateSize (String abbr, string title) { This. abbr =abbr; This. title =title; } PublicString getabbr () {returnabbr; } PublicString GetTitle () {returntitle; } Public StaticSize fromabbr (String abbr) { for(Size size:Size.values ()) {if(Size.getabbr (). Equals (abbr)) {returnsize; } } return NULL; }}
The above code defines two instance variables abbr and title, as well as the corresponding get methods, which represent abbreviations and Chinese names, define a private construction method, accept abbreviations and Chinese names, and each enumeration value passes the corresponding value at the time of definition. A static method fromabbr is also defined to return the corresponding enumeration value according to the abbreviation.
It is necessary to note that the definition of the enumeration value needs to be placed at the top, after the enumeration value is written, you want to end with a semicolon (;), before you can write other code.
The use of this enumeration definition is similar to that of other classes, such as:
Size s == size.fromabbr ("L"); System.out.println (S.gettitle ());
The above code output: M, large
Implementation principle
After adding the instance variables and methods, enumerating the converted classes is similar to the above, just adding the corresponding variables and methods, modifying the construction method, and the code differs in the following example:
Public Final classSizeextendsEnum<size> { Public Static FinalSize SMALL =NewSize ("SMALL", 0, "S", "Trumpet"); Public Static FinalSize MEDIUM =NewSize ("MEDIUM", 1, "M", "Medium"); Public Static FinalSize LARGE =NewSize ("LARGE", 2, "L", "large"); PrivateString abbr; PrivateString title; PrivateSize (String name,intordinal, String abbr, string title) { Super(name, ordinal); This. abbr =abbr; This. title =title; } //... Other Code}
Description
Each enumeration value often has an associated identifier (ID), usually expressed as an int integer, which saves storage space and reduces network transmission. A natural idea is to use the ordinal value that comes with the enumeration, but ordinal is not a good choice.
Why is it? Because the value of ordinal changes as the enumeration value changes position in the definition, in general, we want the relationship between the ID value and the enumeration value to remain the same, especially if the ID of the enumeration value has been saved in many places.
For example, the size example above, the value of Size.small's ordinal is 0, we want 0 to mean size.small, but what if we add a value that represents a very small xsmall?
Public enum Size { xsmall, SMALL, MEDIUM, LARGE}
At this time, 0 means xsmall.
Therefore, it is generally added that an instance variable represents an ID, and another benefit of using an instance variable is that the ID can be defined by itself. For example, the size example can be written as:
Public enum Size { Xsmall (Ten), SMALL (+), MEDIUM (+), LARGE (+); Private int ID; Private Size (int ID) { this. id = ID; } Public int getId () { return ID; }}
Advanced usage
Enumerations also have advanced usages, for example, each enumeration value can have an associated class definition body, an enumeration type can declare an abstract method, a method can be implemented in each enumeration value, or other methods of enumeration types can be overridden.
For example, we look at the changed size code (this code does not really make much sense, the main display syntax):
Public enumSize {SMALL {@Override Public voidOnchosen () {System.out.println ("Chosen small"); }},medium {@Override Public voidOnchosen () {System.out.println ("Chosen Medium"); }},large {@Override Public voidOnchosen () {System.out.println ("Chosen Large"); } }; Public Abstract voidOnchosen ();}
The size enumeration type defines the Onchosen abstract method, which represents the code that executes after the dimension is selected, and a class definition body {} After each enumeration value overrides the Onchosen method.
What is the benefit of this writing? If each or part of the enumeration value has some specific behavior, use this to be concise. For this example, we describe its corresponding switch statement, which executes different code in the switch statement based on the value of size.
The drawback of switch is that the code that defines Swich and the code that defines the enumeration type may not be together, and if you add a new enumeration value, you should also modify the switch code, but you may forget, and if you use an abstract method, you cannot forget that, while defining the enumeration value, The compiler forces the associated behavior code to be defined at the same time. Therefore, if the behavior code and enumeration values are closely related, using the above notation can be more concise, secure and easy to maintain.
How does this kind of writing come true internally? Each enumeration value generates a class that inherits the class of the enumeration type, and then the value-specific class definition body code, and the enumeration value becomes the object of the subclass, and we don't repeat the code.
Enumerations also have other advanced usages, such as enumerations that implement interfaces, or enumerations that can be defined in an interface, with relatively few uses, as described in this article.
Summary
This section describes the enumeration types, describes the basic usage, typical scenarios, and advanced usage, not only describes how to use them, but also describes the implementation principle, and for enumerated types of data, although the direct use of classes can also be handled, the enumeration types are more concise, secure, and convenient.
We've mentioned anomalies before, but we haven't discussed them in depth, let's discuss them in the next section.
----------------
To be continued, check out the latest articles, please pay attention to the public number "old Horse Programming" (Scan the QR code below), from the introduction to advanced, in layman's words, Lao Ma and you explore the nature of Java programming and computer technology. Write attentively, original articles, and keep all copyrights.
-----------
More related original articles
Thinking Logic of computer program (13)-Class
Logic of the computer program (14)-a combination of classes
Thinking Logic of computer program (15)-Initial knowledge inheritance and polymorphism
Logic of the computer program (16)-Details of the inheritance
The thinking Logic of computer program (17)-The basic principle of inheriting implementation
Logic of the computer program (18)-Why inheritance is a double-edged sword.
The thinking Logic of computer program (19)-The nature of the interface
Thinking Logic of computer programs (20)-Why abstract classes?
Thinking Logic of computer programs (21)-The nature of inner classes
The thinking Logic of computer programs (23)-The nature of enumerations