[java basic syntax] detailed enumeration of Java

Posted by Rdam on Mon, 20 Dec 2021 04:03:08 +0100

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

methodexplain
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:

  1. 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
  2. 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

Topics: Java Back-end JavaSE