Today, I'm going to relearn enumeration types in Java.
Why study again now? Because when I first started learning Java, I didn't pay much attention to enumeration. After work, I basically didn't use enumeration. As a result, I don't quite understand the data type of enumeration. Sometimes when I see the enumeration types and related operations used in other people's code, I think they are very good, so I have the impulse to learn again.
Don't say much, start learning!
definition
What does enumeration mean? Baidu Encyclopedia says this:
In mathematical and computer science theory, enumeration of a set is a program that lists all members of some finite sequence set, or a count of a specific type of object. The two types often (but not always) overlap. Is a collection of named integer constants.
Enumerations are common in daily life. For example, SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY and SATURDAY are enumerations.
By mapping this to the Java language, you can define an enumeration class representing the week:
public enum Week { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }
The keyword defining the enumeration class is enum,
Enumerating class objects can't be found through new. The SUNDAY and MONDAY in them are actually instances of enumerating class Week. These are the only fixed instances. You cannot create new instances externally. Direct class and instance name when referencing
Week w = Week.MONDAY;
constructor
Enumeration classes also have constructors, which are modified by private by default, and can only be private. Observe this Code:
public enum Week { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; Week(){ System.out.println("hello"); } } public class Test { public static void main(String[] args) { Week w = Week.FRIDAY; } }
You will find this result:
hello
hello
hello
hello
hello
hello
hello
The constructor is executed seven times, which corresponds to the number of enumerated items in the class. In fact, the creation of this kind of enumeration item is equivalent to other classes calling the object from the parameterless constructor new, that is, this enumeration class has created 7 instances, so 7 hello s are output.
In addition to parameterless constructors, enumeration classes also have parameterless constructors.
public enum Week { SUNDAY(7), MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6); Week(int weekNum){ System.out.println(weekNum); } }
This time will output:
7
1
2
3
4
5
6
Enumerating class members
Like normal classes, enumeration classes can also have member variables, instance methods, static methods, etc.
public enum Week { SUNDAY(7), MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6); private int weekNum; Week(int weekNum){ this.weekNum = weekNum; } public int getWeekNum() { return weekNum; } }
use:
public class Test { public static void main(String[] args) { Week w = Week.FRIDAY; System.out.println(w.getWeekNum()); } }
Output:
5
Enumeration classes can also have abstract methods.
public enum Week { SUNDAY(){ @Override public void getWeekNum() { System.out.println(7); } }, MONDAY() { @Override public void getWeekNum() { System.out.println("Monday"); } }, TUESDAY(){ @Override public void getWeekNum() { System.out.println("Tuesday"); } }, WEDNESDAY(){ @Override public void getWeekNum() { System.out.println("Wednesday"); } }; public abstract void getWeekNum(); } public class Test { public static void main(String[] args) { Week w = Week.TUESDAY; w.getWeekNum(); } }
Output:
Tuesday
values(), valueOf(String name) methods
Each enumeration class has two static methods:
-
static Direction[] values(): returns all enumeration constants of this class;
-
static Direction valueOf(String name): returns the Direction constant by enumerating the name of the constant. Note that this method has different parameters from the valueOf() method in Enum class.
public class Test { public static void main(String[] args) { for (Week w : Week.values()) { System.out.println(w); } System.out.println("Sunday:" + Week.valueOf("SUNDAY")); } }
The results are as follows:
SUNDAY
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY: SUNDAY
Enumeration usage
1. Type constraints
I believe you must have defined constants to use them in the usual development process:
public class Discount { public static final double EIGHT_DISCOUNT = 0.8; public static final double SIX_DISCOUNT = 0.6; public static final double FIVE_DISCOUNT = 0.5; }
In fact, there is no problem with such a definition, but if there is a method like this:
BigDecimal calculatePrice(double discount){ //... }
You need to pass in the commodity discount to calculate the price. If you use the above constant definition, there is no type constraint. You can pass in any value of double type, and the compiler will not issue a warning. If you use enumeration to define this situation, there will be stronger type constraints:
public enum Discount { EIGHT_DISCOUNT(0.8), SIX_DISCOUNT(0.6), FIVE_DISCOUNT(0.5); private double discountNum; Discount(double discountNum) { this.discountNum = discountNum; } double getDiscountNum(){ return discountNum; } }
use:
public class Test { public static void main(String[] args) { calculatePrice(Discount.EIGHT_DISCOUNT); } static BigDecimal calculatePrice(Discount discount){ System.out.println(discount.getDiscountNum()); //... return null; } }
0.8
2. Used in switch
public class Test { public static void main(String[] args) { Week w = Week.MONDAY; switch (w) { case MONDAY: System.out.println("Monday"); break; case TUESDAY: System.out.println("Tuesday"); break; } } }
Monday
3. Implement the interface and eliminate if/else
The enumeration class we created is modified by final by default, and inherits the Enum class by default. Therefore, you can no longer inherit other classes. But you can implement the interface.
There is such a judgment scenario.
if ("dog".equals(animalType)){ System.out.println("Eat bones"); } else if ("cat".equals(animalType)) { System.out.println("Eat dried fish"); } else if ("sheep") { System.out.println("graze"); }
How to eliminate if/else by enumerating? See the following code:
First define an interface with a general method eat()
public interface Eat { //eat String eat(); }
Then create an enumeration class to implement this interface
public enum AnimalEnum implements Eat { Dog(){ @Override public void eat() { System.out.println("Eat bones"); } }, Cat() { @Override public void eat() { System.out.println("Eat dried fish"); } }, Sheep() { @Override public void eat() { System.out.println("graze"); } } }
Only one line of code is required when calling:
public class Test { public static void main(String[] args) { AnimalEnum.valueOf("Cat").eat(); } }
Eat dried fish
And in this way, if I want to expand new animals in the future, I just need to add code to the enumeration class without changing any old code, which is in line with the opening and closing principle!
4. Application in singleton mode
Enumeration can also be used in an implementation of singleton mode.
/** * @Author: * @Description: Enumerating thread safety */ public class SingletonExample { /** * Constructor is privatized to avoid external instance creation */ private SingletonExample(){} private static SingletonExample getInstance() { return Singleton.INSTANCE.getInstance(); } private enum Singleton { INSTANCE; private SingletonExample instance; // The JVM guarantees that this method is absolutely called only once Singleton() { instance = new SingletonExample(); } public SingletonExample getInstance() { return instance; } } }
summary
In fact, Java also has collection classes for enumeration, EnumSet and EnumMap, which we won't describe here.
I've learned a lot.