Series 12 Java lay a solid foundation: a deep understanding of Java reflection mechanism

This series of articles will arrange to me on GitHub's "Java Interview Guide" warehouse, more exciting content please go to my warehouse View

https://github.com/h2pl/Java-Tutorial

Like it under the trouble spots Star Kazakhstan

Article first appeared in my personal blog:

www.how2playlife.com

Enumeration (enum) type is Java 5 new features, it is a new type, allows constants to represent a specific piece of data, but also in the form of all types of security are represented.

On the enumeration class

In programming, sometimes used by a number of limited set of data elements, such as the collection of the week from Monday to Sunday seven data elements, the three colors of red, yellow, green collection consisting of a job within a team consisting of a collection of ten workers and so on, the program is limited to the value of a variable element in the collection. In this case, these data may be defined as a set of enumerated type.

Therefore, enumerated types are possible values ​​of certain types of data collection, such as within a week to week possible values ​​of the set:

  {Sun, Mon, Tue, Wed, Thu, Fri, Sat}

  The collection can be defined as an enumerated type described in the week, a total of seven elements of this enum type, so with enum enumeration type definition of an element can only take the value of the collection. Because enumerated types are derived data type, therefore, it must be defined enumerated types, and then use the enumeration type defined enumeration type variables.

 

    enum <枚举类型名> 
      { <枚举元素表> };
      
      其中:关键词enum表示定义的是枚举类型,枚举类型名由标识符组成,而枚举元素表由枚举元素或枚举常量组成。例如: 
      
    enum weekdays 
      { Sun,Mon,Tue,Wed,Thu,Fri,Sat };
      定义了一个名为 weekdays的枚举类型,它包含七个元素:Sun、Mon、Tue、Wed、Thu、Fri、Sat。
      
> 在编译器编译程序时,给枚举类型中的每一个元素指定一个整型常量值(也称为序号值)。若枚举类型定义中没有指定元素的整型常量值,则整型常量值从0开始依次递增,因此,weekdays枚举类型的七个元素Sun、Mon、Tue、Wed、Thu、Fri、Sat对应的整型常量值分别为0、1、2、3、4、5、6。
>   注意:在定义枚举类型时,也可指定元素对应的整型常量值。复制代码
    例如,描述逻辑值集合{TRUE、FALSE}的枚举类型boolean可定义如下:
    enum boolean 
      { TRUE=1 ,FALSE=0 };
    该定义规定:TRUE的值为1,而FALSE的值为0。
      
    而描述颜色集合{red,blue,green,black,white,yellow}的枚举类型colors可定义如下:
    enum colors 
      {red=5,blue=1,green,black,white,yellow};
      该定义规定red为5 ,blue为1,其后元素值从2 开始递增加1。green、black、white、yellow的值依次为2、3、4、5。
      
  此时,整数5将用于表示二种颜色red与yellow。通常两个不同元素取相同的整数值是没有意义的。枚举类型的定义只是定义了一个新的数据类型,只有用枚举类型定义枚举变量才能使用这种数据类型。 复制代码

Enum class - grammar

enum with class, interface with the same position;

You can inherit multiple interfaces;

You can have a constructor, member methods, member variables;

1.2 differs from the general category of the enumerated classes

The default inherit java.lang.Enum class, so you can not inherit other parent; java.lang.Enum class which implements java.lang.Serializable and java.lang.Comparable interfaces;

Use enum definition, use the default final modification, and therefore can not be subclassed;

Use the default constructor private modification, and only use the private modifier;

Enumerate all instances of the class must be given in the first line, add a default public static final modification, or can not produce examples;

Enumerate specific categories of use

This part reference https://blog.csdn.net/qq_27093465/article/details/52180865

constant


    public class 常量 {
    }
    enum Color {
        Red, Green, Blue, Yellow
    }复制代码

switch

Before JDK1.6 switch statement only supports int, char, enum type, enum, make our code more readable.

    public static void showColor(Color color) {
            switch (color) {
                case Red:
                    System.out.println(color);
                    break;
                case Blue:
                    System.out.println(color);
                    break;
                case Yellow:
                    System.out.println(color);
                    break;
                case Green:
                    System.out.println(color);
                    break;
            }
        }复制代码

Add a new method to enumeration

If you plan to customize your own way, then finally add a semicolon to be serialized in the enum instance. Requirements must be defined and Java enum instance.

    enum Color {
        //每个颜色都是枚举类的一个实例,并且构造方法要和枚举类的格式相符合。
        //如果实例后面有其他内容,实例序列结束时要加分号。
        Red("红色", 1), Green("绿色", 2), Blue("蓝色", 3), Yellow("黄色", 4);
        String name;
        int index;
        Color(String name, int index) {
            this.name = name;
            this.index = index;
        }
        public void showAllColors() {
            //values是Color实例的数组,在通过index和name可以获取对应的值。
            for (Color color : Color.values()) {
                System.out.println(color.index + ":" + color.name);
            }
        }
    }复制代码

Covering methods of enumeration

All enumeration classes inherit from Enum class, that class can override the method is given below a toString example of a method of covering ().

    @Override
    public String toString() {
        return this.index + ":" + this.name;
    }复制代码

Implement an interface

All of the enumeration classes inherit from java.lang.Enum. Because Java does not support multiple inheritance, so enumerable object can not inherit from other classes.

    enum Color implements Print{
        @Override
        public void print() {
            System.out.println(this.name);
        }
    }复制代码

Use Interface organization enumeration

Put forward to implement the interface to organize enumeration, simply speaking, is to classify it. If heavy use enumeration, then, do so, and at the time of writing the code, it is easy to call friends.

    public class 用接口组织枚举 {
        public static void main(String[] args) {
            Food cf = chineseFood.dumpling;
            Food jf = Food.JapaneseFood.fishpiece;
            for (Food food : chineseFood.values()) {
                System.out.println(food);
            }
            for (Food food : Food.JapaneseFood.values()) {
                System.out.println(food);
            }
        }
    }
    interface Food {
        enum JapaneseFood implements Food {
            suse, fishpiece
        }
    }
    enum chineseFood implements Food {
        dumpling, tofu
    }复制代码

Enum class collection

java.util.EnumSet and java.util.EnumMap are two enumerations. EnumSet ensure the collection of elements is not repeated; EnumMap enum type is the key, but may be any type of value.

EnumSet implementation class is not found in the JDK, here to write a EnumMap example

    public class 枚举类集合 {
        public static void main(String[] args) {
            EnumMap<Color, String> map = new EnumMap<Color, String>(Color.class);
            map.put(Color.Blue, "Blue");
            map.put(Color.Yellow, "Yellow");
            map.put(Color.Red, "Red");
            System.out.println(map.get(Color.Red));
        }
    }复制代码

Note the use of enumeration class

image

Comparison between the value of the enumerated type objects, == is used directly to compare values, whether equal, not necessary to use the equals method yo.

Because enumeration Enum class has overridden the equals method

    /**
     * Returns true if the specified object is equal to this
     * enum constant.
     *
     * @param other the object to be compared for equality with this object.
     * @return  true if the specified object is equal to this
     *          enum constant.
     */
    public final boolean equals(Object other) {
        return this==other;
    }复制代码

The principle enumeration class

This part of the reference https://blog.csdn.net/mhmyqn/article/details/48087247

From JDK1.5 Java began to support enumeration, that is to say, it does not support Java began as enumeration, like generics, new features are added only JDK1.5. If you do not provide a feature usually at the outset, was added in the late language development, will encounter a problem, backward compatibility issues.

Like many of the features introduced in Java 1.5, for backward compatibility, the compiler will help us write the source code to do a lot of things, such as why the generic type erasure, why would generate bridging method, foreach iteration, auto-boxing / unpacking, etc., which have a term called "syntactic sugar", while special treatment compiler called "syntactic sugar solution." So like in JDK1.5 enum it is only introduced, but also how to achieve it?

Abstract Java class java.lang.Enum added in 1.5, which is the base class for all enumerated types. It provides some basic properties and basic methods. Meanwhile, the enumeration as a Set and Map also provides support, namely java.util.EnumSet and java.util.EnumMap.

Next, define a simple enumeration class

    public enum Day {
        MONDAY {
            @Override
            void say() {
                System.out.println("MONDAY");
            }
        }
        , TUESDAY {
            @Override
            void say() {
                System.out.println("TUESDAY");
            }
        }, FRIDAY("work"){
            @Override
            void say() {
                System.out.println("FRIDAY");
            }
        }, SUNDAY("free"){
            @Override
            void say() {
                System.out.println("SUNDAY");
            }
        };
        String work;
        //没有构造参数时,每个实例可以看做常量。
        //使用构造参数时,每个实例都会变得不一样,可以看做不同的类型,所以编译后会生成实例个数对应的class。
        private Day(String work) {
            this.work = work;
        }
        private Day() {复制代码
        }
        //枚举实例必须实现枚举类中的抽象方法
        abstract void say ();复制代码
    }复制代码

Decompile results

    D:\MyTech\out\production\MyTech\com\javase\枚举类>javap Day.class
    Compiled from "Day.java"复制代码
    public abstract class com.javase.枚举类.Day extends java.lang.Enum<com.javase.枚举类.Day> {
      public static final com.javase.枚举类.Day MONDAY;
      public static final com.javase.枚举类.Day TUESDAY;
      public static final com.javase.枚举类.Day FRIDAY;
      public static final com.javase.枚举类.Day SUNDAY;
      java.lang.String work;
      public static com.javase.枚举类.Day[] values();
      public static com.javase.枚举类.Day valueOf(java.lang.String);
      abstract void say();
      com.javase.枚举类.Day(java.lang.String, int, com.javase.枚举类.Day$1);
      com.javase.枚举类.Day(java.lang.String, int, java.lang.String, com.javase.枚举类.Day$1);
      static {};
    }复制代码

Can be seen that, after passing through an enumeration compiler into an abstract class, it inherits the java.lang.Enum; enumeration and the enumeration constants defined, into the corresponding public static final properties, and its type on the type of abstract class, the name is the name of the enumeration constants.

At the same time we can see the four internal com .class file class / mikan / Day $ 1.class, com / mikan / Day $ 2.class, com / mikan / Day $ 3.class in the same path Operator.class, com / mikan / Day $ 4.class, that is named after the four fields are used to achieve internal class; while adding two methods values ​​() and valueOf (String); we define the constructor had only one argument, but has become a three parameters; also generates a static block. These specific contents of the next closer look.

Following analysis of the bytecode portions, wherein:

    InnerClasses:
         static #23; //class com/javase/枚举类/Day$4
         static #18; //class com/javase/枚举类/Day$3
         static #14; //class com/javase/枚举类/Day$2
         static #10; //class com/javase/枚举类/Day$1复制代码

It can be seen that there are four inner classes, the four inner classes will analyze the details later.

    static {};
        descriptor: ()V
        flags: ACC_STATIC
        Code:
          stack=5, locals=0, args_size=0
             0: new           #10                 // class com/javase/枚举类/Day$1
             3: dup
             4: ldc           #11                 // String MONDAY
             6: iconst_0
             7: invokespecial #12                 // Method com/javase/枚举类/Day$1."<init>":(Ljava/lang/String;I)V
            10: putstatic     #13                 // Field MONDAY:Lcom/javase/枚举类/Day;
            13: new           #14                 // class com/javase/枚举类/Day$2
            16: dup
            17: ldc           #15                 // String TUESDAY
            19: iconst_1
            20: invokespecial #16                 // Method com/javase/枚举类/Day$2."<init>":(Ljava/lang/String;I)V
            //后面类似,这里省略
    }复制代码

In fact, the compiler generates the static code block to do the following work: four settings are public static final field generated in the compiler generates a static field $ VALUES, save that all enum enumeration type definition the method of constant values ​​added by the compiler:

    public static com.javase.Day[] values();  
      flags: ACC_PUBLIC, ACC_STATIC  
      Code:  
        stack=1, locals=0, args_size=0  
           0: getstatic     #2                  // Field $VALUES:[Lcom/javase/Day;  
           3: invokevirtual #3                  // Method "[Lcom/mikan/Day;".clone:()Ljava/lang/Object;  
           6: checkcast     #4                  // class "[Lcom/javase/Day;"  
           9: areturn  
    这个方法是一个公共的静态方法,所以我们可以直接调用该方法(Day.values()),返回这个枚举值的数组,另外,这个方法的实现是,克隆在静态代码块中初始化的$VALUES字段的值,并把类型强转成Day[]类型返回。复制代码

Why build method adds two parameters?

There is a problem, obviously we constructor parameter only defines a constructor with three parameters Why is it generated?

    从Enum类中我们可以看到,为每个枚举都定义了两个属性,name和ordinal,name表示我们定义的枚举常量的名称,如FRIDAY、TUESDAY,而ordinal是一个顺序号,根据定义的顺序分别赋予一个整形值,从0开始。在枚举常量初始化时,会自动为初始化这两个字段,设置相应的值,所以才在构造方法中添加了两个参数。即:复制代码
    另外三个枚举常量生成的内部类基本上差不多,这里就不重复说明了。复制代码

We can see from the Enum class code defined name and ordinal attributes are final, and most methods are final, especially clone, readObject, writeObject these three methods, these three methods and medals for it is initialized with static code block.

It guarantees the immutability of enumerated type, can not be cloned, serialization and deserialization to enumerate replication, which ensures a constant enumeration is only one example, i.e. a single embodiment, it is recommended in the effective java use enumeration to achieve a single embodiment.

Actual enumeration class

A real no-argument

(1) a non-defined parameter enumeration class

enum SeasonType {
    SPRING, SUMMER, AUTUMN, WINTER
}复制代码

Using (2) the actual

// 根据实际情况选择下面的用法即可
SeasonType springType = SeasonType.SPRING;    // 输出 SPRING 
String springString = SeasonType.SPRING.toString();    // 输出 SPRING复制代码

Two have a real participation

(1) Only the definition of an enumerated type of parameter

enum SeasonType {
    // 通过构造函数传递参数并创建实例
    SPRING("spring"),
    SUMMER("summer"),
    AUTUMN("autumn"),
    WINTER("winter");

    // 定义实例对应的参数
    private String msg;

    // 必写:通过此构造器给枚举值创建实例
    SeasonType(String msg) {
        this.msg = msg;
    }

    // 通过此方法可以获取到对应实例的参数值
    public String getMsg() {
        return msg;
    }
}复制代码

Using (2) the actual

// 当我们为某个实例类赋值的时候可使用如下方式
String msg = SeasonType.SPRING.getMsg();    // 输出 spring复制代码

There are two real three parameters

(1) enumeration class definition has two parameters

public enum Season {
    // 通过构造函数传递参数并创建实例
    SPRING(1, "spring"),
    SUMMER(2, "summer"),
    AUTUMN(3, "autumn"),
    WINTER(4, "winter");

    // 定义实例对应的参数
    private Integer key;
    private String msg;

    // 必写:通过此构造器给枚举值创建实例
    Season(Integer key, String msg) {
        this.key = key;
        this.msg = msg;
    }

    // 很多情况,我们可能从前端拿到的值是枚举类的 key ,然后就可以通过以下静态方法获取到对应枚举值
    public static Season valueofKey(Integer key) {
        for (Season season : Season.values()) {
            if (season.key.equals(key)) {
                return season;
            }
        }
        throw new IllegalArgumentException("No element matches " + key);
    }

    // 通过此方法可以获取到对应实例的 key 值
    public Integer getKey() {
        return key;
    }

    // 通过此方法可以获取到对应实例的 msg 值
    public String getMsg() {
        return msg;
    }
}复制代码

Using (2) the actual

// 输出 key 为 1 的枚举值实例
Season season = Season.valueofKey(1);
// 输出 SPRING 实例对应的 key
Integer key = Season.SPRING.getKey();
// 输出 SPRING 实例对应的 msg
String msg = Season.SPRING.getMsg();复制代码

Enum class summary

In fact, after the enumeration class understand the concept, the enumeration becomes quite simple, and you can readily write out an enumeration class. As so few real small example must first figure out the concept, then practice a few times ok.

Important concept, I am here in the repeat again, the old iron to help them to grasp this knowledge, first remember enumeration value enumeration class can no parameters, you can have multiple parameters, each enumeration values is one example;

And also important it is that if the enumeration value has n parameters, then the parameter value constructor sure there are n because each enumeration value will call the constructor to create an instance of the statement, so it must be a parameter Now understand this, then we just need to put the n parameter is defined as a member of n variables, and then provide the corresponding get () method in the enumeration class, then by example can be free to acquire instance; a corresponding the value of any parameter.

If you want more enumeration class of easy to use, you can imitate my writing as in actual combat III, by a certain parameter values, such as key parameters, will be able to get to their corresponding enumeration value, then the value of what you want , you get what values ​​just fine.

Enumeration API

We use enum defined enumeration class are inherited java.lang.Enum class, it will inherit its API, commonly used API as follows:

  • String name()

Gets an enumeration of name

  • int ordinal()

Enumerated acquisition position (subscript initial value is 0)

  • valueof(String msg)

Acquired by the corresponding enumeration type msg. (Such as in combat or other two enumeration class enumeration classes, as long as the use of this method can be used appropriately)

  • values()

Get all the enumeration class enumeration value (for example, in actual use it to III)

to sum up

It is achieved by a general enumeration class on nature, but the compiler has been processed for us. Every enumeration type inherits from java.lang.Enum, and automatically add the values and valueOf method.

And each enum constant is a constant static field, use the inner class , inner class inherits the enum class. All enumeration constants are initialized by a static block, i.e., during the initialize class loading .

Further by clone, readObject, writeObject these three methods defined as final, while achieving appropriate exception is thrown. This ensures that each enum type and enum constants are immutable. Singleton can be used to enumerate these two features to achieve thread-safe.

Reference article

https://blog.csdn.net/qq_34988624/article/details/86592229https://www.meiwen.com.cn/subject/slhvhqtx.htmlhttps://blog.csdn.net/qq_34988624/article/details/86592229https://segmentfault.com/a/1190000012220863https://my.oschina.net/wuxinshui/blog/1511484https://blog.csdn.net/hukailee/article/details/81107412

Micro-channel public number

Java technology rivers and lakes

If you want to focus on my real time updated articles and dry sharing, you can focus on my public number of rivers and lakes] [Java technology Java, a technical engineer Ali station, the author Huang oblique, focused Java related technologies: SSM, SpringBoot , MySQL, distributed, middleware, cluster, Linux, network, multi-threaded, occasionally speaking point Docker, ELK, as well as dry goods and technology to share the learning experience, committed to the full Java stack development!

Java engineers required Learning Resources: Some Java engineers common learning resources, the number of public attention, background replies keyword "Java" to get free no routine.

My public number

Personal Public Number: Huang oblique

The author is Master 985, ants gold dress JAVA engineer, specializing in JAVA backend technology stack: SpringBoot, MySQL, distributed, middleware, services, but also understand the point of investment banking, occasionally speaking point algorithms and theoretical basis of computer, keep learning and writing, believe in the power of lifelong learning!

Programmers 3T Technology Learning Resources: Some programmers learning resources spree technology, the number of public attention, background replies keyword "data" can get free no routine.

Guess you like

Origin juejin.im/post/5d9aedb2518825095879e62b