preface
Happy New Year to you all as the Spring Festival approaches. Sorted out the Java enumeration related knowledge, is more basic, I hope we learn progress together.
All code demos in this chapter have been uploaded to Github
What is an enumeration type?
JDK5 introduces a new feature. The keyword enum can create a new type from a limited set of named values that can be used as regular program components.
A simple example of an enumeration
enum SeasonEnum {
SPRING,SUMMER,FALL,WINTER;
}
Copy the code
Common methods for enumerating classes
Enum Common methods are as follows:
- name(); Mandatory enum Instance name.
- ordinal(); Returns an int representing the order in which enum instances are declared.
- equals(); Returns a Boolean value, enum Instance equality
- CompareTo () compares the order of enum instances with specified objects
- values(); Mandatory enum Array of instances
- ValueOf (String Name) Gets a constant defined in an enumeration class by name
Let’s get straight to the example:
enum Shrubbery { GROUND,CRAWLING, HANGING} public class EnumClassTest {public static void main(String[] args) {// VALUES Mandatory enum Array of instancesfor(Shrubbery Temp: shrubbery.values ()) {// NAME Mandatory Instance enum Declared name System.out.println(temp.name() +" ordinal is " + temp.ordinal() + " ,equal result is " +
Shrubbery.CRAWLING.equals(temp) + ",compare result is "+ Shrubbery.CRAWLING.compareTo(temp)); System.out.println(shrubbery.valueof ()); // Get the constant value defined in the enumeration class by name."CRAWLING")); }}Copy the code
Running results:
GROUND ordinal is 0 ,equal result is false,compare result is 1
CRAWLING ordinal is 1 ,equal result is true,compare result is 0
HANGING ordinal is 2 ,equal result is false,compare result is -1
CRAWLING
Copy the code
Enumerators
What exactly are enumerated types? Let’s create a simple enumeration to see what it looks like. As follows:
public enum Shrubbery {
GROUND,CRAWLING, HANGING
}
Copy the code
Compile the above enumerated classes using Javac, resulting in the Shrubbery. Class file.
javac Shrubbery.java
Copy the code
Then use javap command, decompile to get the bytecode file. For example, run javap Shrubbery. Class to obtain the following bytecode files.
Compiled from "Shrubbery.java"
public final class enumtest.Shrubbery extends java.lang.Enum<enumtest.Shrubbery> {
public static final enumtest.Shrubbery GROUND;
public static final enumtest.Shrubbery CRAWLING;
public static final enumtest.Shrubbery HANGING;
public static enumtest.Shrubbery[] values();
public static enumtest.Shrubbery valueOf(java.lang.String);
static {};
}
Copy the code
From the bytecode file you can see:
- The Shrubbery enumeration becomes a final modified class, that is, it cannot be inherited.
- Shrubbery is a subclass of java.lang.Enum.
- Shrubbery defines enumerations that are public static final.
For a closer look, javap decompiles with multiple arguments -c and executes the following command:
javap -c Shrubbery.class
Copy the code
The bytecode file for the static code block is as follows:
static {};
Code:
0: new #4 // class enumtest/Shrubbery
3: dup
4: ldc #7 // String GROUND
6: iconst_0
7: invokespecial #8 // Method "
":(Ljava/lang/String; I)V
10: putstatic #9 // Field GROUND:Lenumtest/Shrubbery;
13: new #4 // class enumtest/Shrubbery
16: dup
17: ldc #10 // String CRAWLING
19: iconst_1
20: invokespecial #8 // Method "
":(Ljava/lang/String; I)V
23: putstatic #11 // Field CRAWLING:Lenumtest/Shrubbery;
26: new #4 // class enumtest/Shrubbery
29: dup
30: ldc #12 // String HANGING
32: iconst_2
33: invokespecial #8 // Method "
":(Ljava/lang/String; I)V
36: putstatic #13 // Field HANGING:Lenumtest/Shrubbery;
39: iconst_3
40: anewarray #4 // class enumtest/Shrubbery
43: dup
44: iconst_0
45: getstatic #9 // Field GROUND:Lenumtest/Shrubbery;
48: aastore
49: dup
50: iconst_1
51: getstatic #11 // Field CRAWLING:Lenumtest/Shrubbery;
54: aastore
55: dup
56: iconst_2
57: getstatic #13 // Field HANGING:Lenumtest/Shrubbery;
60: aastore
61: putstatic #1 // Field $VALUES:[Lenumtest/Shrubbery;
64: return
}
Copy the code
- Lines 0-39 instantiate the Shrubbery enumeration classes’ GROUND,CRAWLING, HANGING;
- 40-64 Creates the Shrubbery[] array $VALUES and places the above three instantiated objects in the array.
- Therefore, the enumeration class method values() returns an enum array of enumerated instances.
Fourth, the advantages of enumerated classes
What are the advantages of enumerated classes? Why did we choose to use enumerated classes? Because it makes code more readable, more maintainable, and more secure.
Enumerated classes enhance readability and maintainability
Suppose you have a business scenario where, after an order is completed, the buyer is notified to comment. It is easy to have the following code:
// Order completedif(3==orderStatus){
//do something
}
Copy the code
Apparently, this code has magic numbers, and if you don’t comment it, who knows what status 3 represents, which is not only difficult to read, but also a pain to maintain? How about using an enumeration class, as follows:
public enum OrderStatusEnum {
UNPAID(0, "Unpaid"), PAID(1, "Paid"), SEND(2, "Shipped"), FINISH(3, "Done"),;
private int index;
private String desc;
public int getIndex() {
return index;
}
public String getDesc() {
returndesc; } OrderStatusEnum(int index, String desc) { this.index = index; this.desc = desc; }} // Order completedif(OrderStatusEnum.FINISH.getIndex()==orderStatus){
//do something
}
Copy the code
As you can see, enumerations make this code more readable and easier to maintain. Add a new order state, just add one more enumeration state. Public static final int public static final int public static final int
New Jersey = New Jersey; New Jersey = New Jersey; New Jersey = New Jersey; public static final int PAID = 1; public static final int SENDED = 2; public static final int FINISH = 3; } // Order completedif(OrderStatus.FINISH==orderStatus){
//do something
}
Copy the code
Of course, there is no problem with readability when static constants are implemented, and there is nothing wrong with writing code this way in everyday life. However, if you define a variable with the same int value, it will be confusing. If you define both PAID and SENDED states as 2, the compiler will not report an error.
Therefore, the first advantage of enumerated classes is readability and maintainability, so it is recommended.
Enumeration class security
In addition to readability and maintainability, enumerated classes have the great advantage of being secure.
From the enumeration class bytecode analysis in the previous section, we know:
- An enumerated class is decorated with the final keyword and cannot be inherited.
- And its variables are public static final, are static variables.
Static resources are initialized, Java classes are loaded, and the initialization process is thread-safe when a Java class is actually used for the first time.
Common uses of enumerations
Enum Organization constant
Before JDK5, constant definitions used to be like this: first define a class or interface, and the property type is public static final… Once you have enumerations, you can organize constants into enumerated classes as follows:
enum SeasonEnum {
SPRING,SUMMER,FALL,WINTER,;
}
Copy the code
Enum and Switch are interlinked
In general, only integer values can be used in switch-case, but enumeration instances naturally have an order of integer values. Therefore, enums can be used in switch statements, as follows:
enum OrderStatusEnum {
UNPAID, PAID, SEND, FINISH
}
public class OrderStatusTest {
public static void main(String[] args) {
changeByOrderStatus(OrderStatusEnum.FINISH);
}
static void changeByOrderStatus(OrderStatusEnum orderStatusEnum) {
switch (orderStatusEnum) {
case UNPAID:
System.out.println("Boss, you placed your order. Pay now.");
break;
case PAID:
System.out.println("I already paid for it.");
break;
case SENDED:
System.out.println("Shipped");
break;
case FINISH:
System.out.println("Order fulfilled.");
break; }}}Copy the code
In daily development, enum is used with switch to make your code more readable.
Add a new method to the enumeration
You can add new methods to an enumeration class, such as get methods, ordinary methods, etc.
public enum OrderStatusEnum {
UNPAID(0, "Unpaid"), PAID(1, "Paid"), SENDED(2, "Shipped"), FINISH(3, "Done"),; Private int index; private String desc; //get method public intgetIndex() {
return index;
}
public String getDesc() {
returndesc; } // Constructor method OrderStatusEnum(int index, String desc) {this.index = index; this.desc = desc; } public static OrderStatusEnum of(int index){for (OrderStatusEnum temp : values()) {
if (temp.getIndex() == index) {
returntemp; }}returnnull; }}Copy the code
Enumeration implementation interface
All enumerated classes inherit from java.lang.Enum, so enumerations can no longer inherit from other classes. But enumerations can implement interfaces, which adds color to enumerations. As follows:
public interface ISeasonBehaviour {
void showSeasonBeauty();
String getSeasonName();
}
public enum SeasonEnum implements ISeasonBehaviour {
SPRING(1,"Spring"),SUMMER(2,"Summer"),FALL(3,"Autumn"),WINTER(4,"Winter"),; private int index; private String name; SeasonEnum(int index, String name) { this.index = index; this.name = name; } public intgetIndex() {
return index;
}
public String getName() {
returnname; } // Override public voidshowSeasonBeauty() {
System.out.println("welcome to "+ this.name); } // Override public StringgetSeasonName() {
returnthis.name; }}Copy the code
Use interfaces to organize enumerations
public interface Food {
enum Coffee implements Food{
BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
}
enum Dessert implements Food{
FRUIT, CAKE, GELATO
}
}
Copy the code
== = equals == =
Here’s an example:
public class EnumTest {
public static void main(String[] args) {
Shrubbery s1 = Shrubbery.CRAWLING;
Shrubbery s2 = Shrubbery.GROUND;
Shrubbery s3 = Shrubbery.CRAWLING;
System.out.println("s1==s2,result: " + (s1 == s2));
System.out.println("s1==s3,result: " + (s1 == s3));
System.out.println("Shrubbery. CRAWLING. Equals (s1), the result:"+Shrubbery.CRAWLING.equals(s1));
System.out.println("Shrubbery.CRAWLING.equals(s2),result: "+Shrubbery.CRAWLING.equals(s2)); }}Copy the code
Running results:
s1==s2,result: false
s1==s3,result: trueShrubbery. CRAWLING. Equals (s1), the result:true
Shrubbery.CRAWLING.equals(s2),result: false
Copy the code
You can see that it doesn’t matter whether you use == or equals. Actually the enumeration equals method, is to use the = = comparison, as follows:
public final boolean equals(Object other) {
return this==other;
}
Copy the code
Enumeration of implementation singletons
Effective Java mentioned that the best singleton implementation pattern is the enumeration pattern. There are several ways to implement the singleton pattern. Why is enumeration the best?
Because singletons implemented by enumeration have the following advantages:
- Enumeration singletons are simple to write
- Enumerations solve thread-safety problems
- Enumerations solve the problem of deserialization breaking singletons
An enumeration singleton demo looks like this:
public class SingletonEnumTest {
public enum SingletonEnum {
INSTANCE,;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) {
SingletonEnum.INSTANCE.setName("jay@huaxiao"); System.out.println(SingletonEnum.INSTANCE.getName()); }}Copy the code
There is about enumeration implementation singleton, want to in-depth understanding of the friends can see Hollis god this article, written really good! Why do I recommend using enumerations to implement singletons?
EnumSet and EnumMap
EnumSet
Let’s start with EnumSet’s inheritance diagram
Obviously, EnumSet also implements the set interface, which has the following advantages over HashSet:
- Consumes less memory
- It’s more efficient because it’s a bit vector implementation.
- Predictable traversal order (declaration order of enum constants)
- Refuse to add null
EnumSet is a high performance implementation of set. The requirement is to store the same enumeration type. Common methods of enumsetting:
- Allof () creates an EnumSet containing all the enumeration values in the specified enumeration class
- Range () gets an enumeration instance of a range
- Of () creates an EnumSet containing all the enumeration elements in the argument
- The initial enumeration of () includes the complementOf the specified enumeration set
Look at the examples, the most practical:
public class EnumTest {
public static void main(String[] args) {
// Creating a set
EnumSet<SeasonEnum> set1, set2, set3, set4;
// Adding elements
set1 = EnumSet.of(SeasonEnum.SPRING, SeasonEnum.FALL, SeasonEnum.WINTER);
set2 = EnumSet.complementOf(set1);
set3 = EnumSet.allOf(SeasonEnum.class);
set4 = EnumSet.range(SeasonEnum.SUMMER,SeasonEnum.WINTER);
System.out.println("Set 1: " + set1);
System.out.println("Set 2: " + set2);
System.out.println("Set 3: " + set3);
System.out.println("Set 4: " + set4); }}Copy the code
Output result:
Set 1: [SPRING, FALL, WINTER]
Set 2: [SUMMER]
Set 3: [SPRING, SUMMER, FALL, WINTER]
Set 4: [SUMMER, FALL, WINTER]
Copy the code
EnumMap
The inheritance system diagram of EnumMap is as follows:
EnumMap also implements the Map interface, which also has these advantages over HashMap:
- Consumes less memory
- More efficient
- Predictable traversal order
- Reject the null
EnumMap is a high-performance implementation of Map. Its common approach is identical to that of a HashMap, with the only constraint being enumeration correlation.
Look at the examples, the most practical:
public class EnumTest {
public static void main(String[] args) {
Map<SeasonEnum, String> map = new EnumMap<>(SeasonEnum.class);
map.put(SeasonEnum.SPRING, "Spring");
map.put(SeasonEnum.SUMMER, "Summer");
map.put(SeasonEnum.FALL, "Autumn");
map.put(SeasonEnum.WINTER, "Winter"); System.out.println(map); System.out.println(map.get(SeasonEnum.SPRING)); }}Copy the code
The results
{SPRING= SPRING, SUMMER= SUMMER, FALL= autumn, WINTER= WINTERCopy the code
Ix. To be updated
There are key points about enumeration, dear friends, do you have anything to add?
Reference and thanks
- An in-depth analysis of enumerations in Java
- An in-depth analysis of Java enumeration types — thread safety and serialization of enumerations
- Why do I recommend using enumerations to implement singletons?
- In-depth understanding of Java enumeration types (EnUms)
- Understand Java enumerations in depth
- EnumSet in Java
- Java enumeration (enum) explains the seven common uses
- Ideas for Java Programming
Personal public account
- If you are a good boy who loves learning, you can follow my public account and study and discuss with me.
- If you feel that this article is not correct, you can comment, you can also follow my public account, private chat me, we learn and progress together.