Thinking logic of computer programs (23) and thinking 23

Source: Internet
Author: User

Thinking logic of computer programs (23) and thinking 23

In the previous series, we introduced the basic data types, classes, and interfaces used to represent and operate data in Java. This section discusses enumeration types in Java.

Enumeration is a special type of data. Its values are limited and can be enumerated. For example, a year has four seasons and a week has seven days, although classes can also process such data, enumeration types are more concise, secure, and convenient.

Next we will introduce the use of enumeration and its implementation principles.

Basic

Basic usage

Defining and using basic enumeration is relatively simple. Let's take a look at an example. To represent the clothes Size, we define an enumeration type Size, which includes three sizes: small/medium/large, the Code is as follows:

public enum Size {    SMALL, MEDIUM, LARGE}

The enum keyword is used for enumeration. The Size includes three values, which indicate small, medium, and large. The values are generally uppercase letters. Multiple values are separated by commas. The enumeration type can be defined as a separate file or in other classes.

You can use Size as follows:

Size size = Size.MEDIUM

Size size declares the size of a variable. Its type is Size, size = Size. MEDIUM assigns the enumerated value MEDIUM to the size variable.

The toString method of the enumerated variable returns its literal value. All enumeration types also have a name () method. The returned value is the same as that of toString (). For example:

Size size = Size.SMALL;System.out.println(size.toString());System.out.println(size.name());

The output is all.

You can use equals and = to compare the enumerated variables. The results are the same, for example:

Size size = Size.SMALL;System.out.println(size==Size.SMALL);System.out.println(size.equals(Size.SMALL));System.out.println(size==Size.MEDIUM);

The output result of the above Code is three rows: true, true, and false.

The enumerated values are ordered and can be compared. Each Enumeration type has a method int ordinal (), which indicates the order in which the enumeration values are declared, starting from 0. For example, the following code output is 1:

Size size = Size.MEDIUM;System.out.println(size.ordinal());

In addition, the enumerated types all implement the Comparable interface in Java API. You can use the compareTo method to compare the compareTo with other enumerated values. The comparison is actually to compare the ordinal size, for example, the following code output is-1, indicating that SMALL is smaller than MEDIUM:

Size size = Size.SMALL;System.out.println(size.compareTo(Size.MEDIUM));

Enumeration variables can be used in the same places as other types of variables, such as method parameters, class variables, and instance variables. enumeration can also be used in switch statements. The Code is as follows:

static void onChosen(Size size){    switch(size){    case SMALL:        System.out.println("chosen small"); break;    case MEDIUM:        System.out.println("chosen medium"); break;    case LARGE:        System.out.println("chosen large"); break;    }}

In a switch statement, the enumerated values cannot contain the enumeration type prefix. For example, if you use SMALL directly, you cannot use Size. SMALL.

All enumeration types have a static valueOf (String) method, which can return the enumerated value corresponding to the String. For example, the following code outputs true:

System.out.println(Size.SMALL==Size.valueOf("SMALL"));

The enumerated type also has a static values method, which returns an array containing all enumerated values in the same order as the declared order. For example:

for(Size size : Size.values()){    System.out.println(size);}

The screen output contains three rows: SMALL, MEDIUM, and LARGE.

Benefits of enumeration

Java supports enumeration only from JDK 5. Before that, it generally defines static integer variables in the class to implement similar functions. The Code is as follows:

class Size {    public static final int SMALL = 0;    public static final int MEDIUM = 1;    public static final int LARGE = 2;}

The benefit of enumeration is obvious:

  • The syntax for defining enumeration is more concise.
  • Enumeration is more secure. For a variable of Enumeration type, its value is either null or one of the enumerated values. It cannot be another value, but an integer variable is used, its value cannot be forced, and the value may be invalid.
  • The enumeration type comes with many convenient methods (such as values, valueOf, and toString), which are easy to use.

Basic implementation principle

The enumeration type is actually converted into a corresponding class by the Java compiler, which inherits the Java. lang. Enum class in the java API.

The Enum class has two instance variables: name and ordinal, which must be passed in the constructor: name (), toString (), ordinal (), compareTo (), and equals () methods are implemented by the Enum class according to its instance variable name and ordinal.

The values and valueOf methods are automatically added to each Enumeration type by the compiler. The code of the general class after the Size conversion of the enumeration type is roughly as follows:

public final class Size extends Enum<Size> {    public static final Size SMALL = new Size("SMALL",0);    public static final Size MEDIUM = new Size("MEDIUM",1);    public static final Size LARGE = new Size("LARGE",2);        private static Size[] VALUES =            new Size[]{SMALL,MEDIUM,LARGE};        private Size(String name, int ordinal){        super(name, ordinal);    }        public static Size[] values(){        Size[] values = new Size[VALUES.length];        System.arraycopy(VALUES, 0,                values, 0, VALUES.length);        return values;    }        public static Size valueOf(String name){        return Enum.valueOf(Size.class, name);    }}

Explanations:

  • Size is final and cannot be inherited. Enum <Size> indicates the parent class, and <Size> indicates generic writing. This can be ignored in subsequent articles.
  • Size has a private constructor that accepts name and ordinal and passes it to the parent class. Private indicates that a new instance cannot be created externally.
  • The three enumerated values are actually three static variables, which are also final and cannot be modified.
  • The values method is added by the compiler, and an internal values array keeps all enumeration values.
  • The valueOf method calls the method of the parent class, and the parameter Size is passed. class indicates the type information of the class. We will introduce the type information in subsequent articles. The parent class actually calls the values method and obtains the corresponding enumerated value based on the name comparison.

Generally, the enumerated variable is converted to the corresponding class variable. In the switch statement, the enumerated value is converted to its corresponding ordinal value.

It can be seen that the enumeration type is essentially a class, but because the compiler does many things automatically, its usage is more concise, secure, and convenient.

Typical scenarios

Usage

The above enumeration is the simplest method. In practice, enumeration often involves associated instance variables and methods. For example, in the above Size example, each enumerated value may have associated abbreviations and Chinese names, the static method may be required to return the corresponding enumerated value according to the abbreviation. The modified Size code is as follows:

Public enum Size {SMALL ("S", "SMALL"), MEDIUM ("M", "MEDIUM"), LARGE ("L", "LARGE "); private String abbr; private String title; private Size (String abbr, String title) {this. abbr = abbr; this. title = title;} public String getAbbr () {return abbr;} public String getTitle () {return title;} public static Size fromAbbr (String abbr) {for (Size size Size: size. values () {if (size. getAbbr (). equals (abbr) {return size ;}} return null ;}}

The code above defines two instance variables: abbr and title, and the corresponding get method, which respectively represent the abbreviations and Chinese names. It defines a private constructor that accepts abbreviations and Chinese names, each enumeration value is defined by passing the corresponding value, and a static method fromAbbr is defined to return the corresponding enumeration value according to the abbreviation.

It should be noted that the definition of the enumerated value must be placed at the top. After the enumerated value is written, it must end with a semicolon (;) before writing other code.

The usage of this enumeration definition is similar to that of other classes, for example:

Size s = Size.MEDIUM;System.out.println(s.getAbbr());s = Size.fromAbbr("L");System.out.println(s.getTitle());

The above code is output respectively: M, large

Implementation Principle

After adding the instance variables and methods, the classes after enumeration conversion are similar to the above, but the corresponding variables and methods are added and the constructor method is modified. The differences in the Code are roughly as follows:

Public final class Size extends Enum <Size> {public static final Size SMALL = new Size ("SMALL", 0, "S", "SMALL "); public static final Size MEDIUM = new Size ("MEDIUM", 1, "M", "MEDIUM"); public static final Size LARGE = new Size ("LARGE", 2, "L", ""); private String abbr; private String title; private Size (String name, int ordinal, String abbr, String title) {super (name, ordinal ); this. abbr = abbr; this. title = title ;}//... other code}

Description

Each enumerated value often has an associated identifier (id), which is usually expressed by an int integer. Using an integer can save storage space and reduce network transmission. A natural idea is to use the ordinal value in enumeration, but ordinal is not a good choice.

Why? Because the ordinal value changes with the position of the enumerated value in the definition, but in general, we want the relationship between the id value and the enumerated value to remain unchanged, especially when the IDs of enumerated values are saved in many places.

For example, in the above Size example, the ordinal value of Size. SMALL is 0, and we want 0 to represent Size. SMALL. But what if we add a value that represents the super small xsmall?

public enum Size {    XSMALL, SMALL, MEDIUM, LARGE}

In this case, 0 indicates XSMALL.

Therefore, an instance variable is added to indicate the id. Another advantage of using the instance variable is that the id can be defined by yourself. For example, the Size can be written as follows:

public enum Size {    XSMALL(10), SMALL(20), MEDIUM(30), LARGE(40);        private int id;    private Size(int id){        this.id = id;    }    public int getId() {        return id;    }}

Advanced usage

Enumeration also has some advanced usage. For example, each enumeration value can have an associated class definition body. The Enumeration type can declare an abstract method, and each enumeration value can implement this method, you can also override other methods of the enumeration type.

For example, let's look at the modified Size code (this code is of little practical significance and mainly shows the syntax ):

public enum Size {    SMALL {        @Override        public void onChosen() {            System.out.println("chosen small");        }    },MEDIUM {        @Override        public void onChosen() {            System.out.println("chosen medium");        }    },LARGE {        @Override        public void onChosen() {            System.out.println("chosen large");        }    };        public abstract void onChosen();} 

The Size Enumeration type defines the onChosen abstract method, indicating the code executed after this Size is selected. Each enumerated value is followed by a class definition body {}, and the onChosen method is overwritten.

What are the advantages of this writing method? If each or part of the enumerated values has some specific behaviors, this method is concise. In this example, we have introduced the corresponding switch statement, in which different code is executed according to the size value.

The disadvantage of switch is that the Code defining swich and the Code defining enumeration types may be different. If an enumeration value is added, you must modify the switch code as well, but you may forget it, if an abstract method is used, it cannot be forgotten. When defining enumeration values, the compiler will force the relevant behavior code to be defined at the same time. Therefore, if the behavior code is closely related to the enumeration value, the above method can be simpler, safer, and easier to maintain.

How is this writing implemented internally? Each enumerated value generates a class that inherits the class corresponding to the enumeration type, and then adds the class definition code with a specific value. The enumerated value becomes the object of this subclass, we will not go into details about the specific code.

Enumeration also has some other advanced usage. For example, enumeration can be used to implement interfaces, or enumeration can be defined in Interfaces. This document will not introduce enumeration.

Summary

This section describes enumeration types, basic usage, typical scenarios, and advanced usage. It not only describes how to use enumeration types, but also introduces implementation principles, although classes can be processed directly, enumeration types are more concise, secure, and convenient.

We have mentioned exceptions before, but we have not discussed them in depth. Let's discuss them in the next section.

----------------

For more information, see the latest article. Please pay attention to the Public Account "lauma says programming" (scan the QR code below), from entry to advanced, ma and you explore the essence of Java programming and computer technology. Write with your heart, original articles, and retain all copyrights.

-----------

More original articles

Thinking logic of computer programs (13)-class

Thinking logic of computer programs (14)-combination of Classes

Thinking logic of computer programs (15)-inheritance and Polymorphism

Thinking logic of computer programs (16)-Details of Inheritance

Thinking logic of computer programs (17)-Basic Principle of inheritance implementation

Thinking logic of computer programs (18)-Why inheritance is a double-edged sword

Thinking logic of computer programs (19)-essence of interfaces

Thinking logic of computer programs (20)-Why abstract classes?

Thinking logic of computer programs (21)-nature of internal classes

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.