1. Definitions
Java enumeration is a special class, which generally represents a set of constants, such as 4 seasons of a year, 12 months of a year, 7 days of a week, Southeast, northwest and so on. Similarly, when a variable has several fixed possible values, it can be defined as an enumeration type
Definition form:
Modifier enum Enumeration name:Foundation type { Enumeration members, }
- Any two enumeration members cannot have the same name, and its constant value must be within the range of the underlying type of the enumeration. Multiple enumeration members are separated by commas.
- When there are properties other than enumeration members, the enumeration members must be on the first line and end with semicolons
- The basic type of enumeration can be declared without display, that is, the basic type can not be added after the enumeration name
- If the underlying type of the enumeration is not explicitly declared, it means that its corresponding underlying type is int
Example code: use enumeration class to define season
public enum Season { spring,summer,fall,winter; }
Supplement:
-
enum keyword is used to define enumeration class in Java, and its status is the same as that of class and interface
-
Enumeration class is a special class. Like ordinary classes, it has its own member variables, member methods and construction methods
-
The constructor of enumeration class is modified by private by default (and can only be modified by private), so the constructor cannot be called externally (that is, Enum cannot be instantiated). The constructor is only called when constructing enumeration values
-
Enum classes defined with enum inherit Java. Net by default Lang. enum class (although inheritance is not shown), and implements two interfaces: java.lang.serializable and java.lang.Comparable
-
All enumeration values are public static final, and non Abstract enumeration classes cannot generate subclasses
-
All instances (enumeration values) of the enumeration class must be explicitly listed in the first row of the enumeration class, otherwise the enumeration class will never generate instances. When these instances (enumeration values) are listed, the system will automatically add the public static final modifier, which does not need to be explicitly added by the programmer
-
When defining an enumeration type, each enumeration type member can be regarded as an instance of Enum class, that is, the enumeration value is an object
-
Like ordinary classes, enumeration classes can implement one or more interfaces. When an enumeration class implements an interface, it also implements all the methods of the interface
2. Use
2.1 enumeration types can be used in switch statements
In Java, the expression in switch (expression) has type restrictions
It can only use integers (only byte, short, int), characters (char), strings (String), and enumeration types
Example of switch statement expression using enumeration:
public enum Season { spring,summer,fall,winter; public static void main(String[] args) { Season season=Season.summer; switch(season){ case spring: System.out.println("spring"); break; case summer: System.out.println("summer"); break; case fall: System.out.println("autumn"); break; case winter: System.out.println("winter"); break; default: break; } } } // The result is: Summer
2.2 common internal methods of enumeration classes
method | explain |
---|---|
values() | Returns all members of an enumerated type as an array |
ordinal() | Gets the index location of the enumeration member |
valueOf() | Returns the enumeration constant of the specified string value. If it does not exist, an IllegalArgumentException will be reported |
compareTo() | Compares the order in which two enumeration members are defined |
Example 1: returns all members of an enumerated type as an array
public enum Season { spring,summer,fall,winter; public static void main(String[] args) { Season[] seasons=Season.values(); for(Season s: seasons){ System.out.print(s+" "); } } } // The result is: spring summer fall winter
Example 2: get the index position of enumeration members
public enum Season { spring,summer,fall,winter; public static void main(String[] args) { Season[] seasons=Season.values(); for(Season s: seasons){ System.out.println(s.ordinal()+": "+s); } } } /** The result is: 0: spring 1: summer 2: fall 3: winter */
Example 3: returns the enumeration constant of the specified string value
public enum Season { spring,summer,fall,winter; public static void main(String[] args) { System.out.println(Season.valueOf("spring")); System.out.println(Season.valueOf("Monday")); } }
Example 4: comparing the order of two enumeration members when they are defined
public enum Season { spring,summer,fall,winter; public static void main(String[] args) { System.out.println(spring.compareTo(summer)); System.out.println(spring.compareTo(winter)); } } // The result is: - 1 - 3
2.3 construction method of user-defined enumeration
When defining an enumeration type, each enumeration type member can be regarded as an instance of Enum class, that is, the enumeration value is an object
If the enumeration object has parameters, you need to provide the corresponding construction method, and the construction method should be private
Example:
public enum Season { spring("spring"),summer("summer"),fall("autumn"),winter("winter"); public String name; private Season(String name){ this.name=name; } public static void main(String[] args) { Season[] seasons=Season.values(); for(Season s: seasons){ System.out.println(s.name); } } } // The results are as follows: spring, summer, autumn and winter
2.4 enumeration classes containing abstract methods
Define an Operation enumeration class, which has four enumeration values: plus, min, mul and div, representing addition, subtraction, multiplication and division respectively. And the enumeration class has a calculate() method for calculation
Example:
public enum Operation { plus{ @Override public double calculate(double a, double b) { return a+b; } }, min{ @Override public double calculate(double a, double b) { return a-b; } }, mul{ @Override public double calculate(double a, double b) { return a*b; } }, div{ @Override public double calculate(double a, double b) { return a/b; } }; public abstract double calculate(double a,double b); public static void main(String[] args) { System.out.println(Operation.plus.calculate(20,10)); System.out.println(Operation.min.calculate(20,10)); System.out.println(Operation.mul.calculate(20,10)); System.out.println(Operation.div.calculate(20,10)); } } // The result is: 30.0 10.0 200.0 2.0
3. Enumeration classes cannot obtain instances through reflection (interview questions)
Because the construction method of enumeration is private, the instance of enumeration class cannot be obtained directly. Can I get the enumerated instance object through reflection? Next, let's try
Try Code:
public enum Season { spring("spring"),summer("summer"),fall("autumn"),winter("winter"); public String chineseName; private Season(String chineseName){ this.chineseName=chineseName; } public static void reflectPrivateConstructor(){ Class c=null; try { // Get Class object c=Class.forName("Season"); // Get construction method Constructor<?> constructor=c.getDeclaredConstructor(String.class); constructor.setAccessible(true); // Call the newInstance method of the Constructor to instantiate Season season=(Season) constructor.newInstance("spring"); System.out.println(season); } catch (ClassNotFoundException | NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static void main(String[] args) { reflectPrivateConstructor(); } }
Running result: Java. Net appears Lang. nosuchmethodexception means that there is no such constructor
Cause analysis:
When we customize an enumeration class, it will inherit from Java by default Lang. Enum, so Enum is equivalent to the parent class of our custom enumeration class. When instantiating a child class, we need to construct it for the parent class first, but we don't construct it for the parent class in the above code.
Enum source code analysis:
- First, by analyzing the definition of Enum, we find that it is an abstract class, so our custom enumeration class will inherit it by default
- Secondly, by analyzing the construction method of Enum, we find that it has only one construction method and two parameters
Help parent class construction:
In enumeration, instead of using super to help the parent class construct, we need to add two parameters in the parent class construction method to the getdeclaraedconstructor () method to obtain the construction method during reflection, that is, the construction method of our custom enumeration class in the above code has a parameter chineseName, plus the name and ordinal in the parent class construction method, Therefore, the getdeclaraedconstructor () method should have three parameters. Pay attention to the order of parameters. First put the parameters of the parent class construction method, and then the parameters of the child class
Modified code:
public enum Season { spring("spring"),summer("summer"),fall("autumn"),winter("winter"); public String chineseName; private Season(String chineseName){ this.chineseName=chineseName; } public static void reflectPrivateConstructor(){ Class c=null; try { // Get Class object c=Class.forName("Season"); // Get private object Constructor<?> constructor=c.getDeclaredConstructor(String.class,int.class,String.class); constructor.setAccessible(true); Season season=(Season) constructor.newInstance("spring"); System.out.println(season); } catch (ClassNotFoundException | NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static void main(String[] args) { reflectPrivateConstructor(); } }
Running result: Java. Net appears Lang. illegalargumentexception exception, and it also said cannot reflexively create enum objects, that is, enumeration objects cannot be created through reflection
Cause analysis:
By reporting an error, we can know that the error occurred when using the Constructor's newInstance() method, so let's check its source code
It is clear through the source code, and the creation of enumerated objects through reflection has been eliminated in the source code
4. Advantages and disadvantages of enumeration
advantage:
- Enumerating constants is simpler and safer
- Enumeration has built-in methods
Disadvantages:
- Enumeration cannot inherit
- Enumeration cannot be extended