Twelve: Enumeration and Annotation

--------

Statement: This article was modified on the basis of an original article by CSDN blogger "lsqstudy", following the CC 4.0 BY-SA copyright agreement

Original Link: https://blog.csdn.net/PorkBird/article/details/113666542

01, Enumeration Classes

1.0, Overview of Enumerated Classes

1. The number of objects in a class is finite and deterministic. We call this class an enumeration class. Examples are as follows:

  • Week: Monday,..., Sunday
  • Gender: Man (male), Woman (female)
  • Season: Spring (Spring Festival)...Winter (Winter)
  • Payment methods: Cash (cash), WeChatPay (WeChat), Alipay (Alipay), BankCard (bank card), CreditCard (credit card)
  • Initiation status: Busy, Free, Vocation, Dimission
  • Order status: Nonpayment (unpaid), Paid (paid), Delivered (shipped), Return (returned), Checked (confirmed) Fulfilled (dispatched),
  • Thread state: Create, Ready, Run, Block, Death

2. Enumeration classes are strongly recommended when you need to define a set of constants

3. If the enumeration has only one object, it can be implemented as a singleton pattern.

4. How to define an enumeration class

  • Mode 1: Require custom enumeration classes before JDK1.5
  • Mode 2: JDK 1.5 adds an enum keyword to define an enum class

5. Attributes of Enumerated Classes

  • The properties of enumerated class objects should not be allowed to be altered, so private final should be used to decorate them
  • Attributes of enumerated classes decorated with private final should be assigned to them in the constructor
  • If an enumeration class explicitly defines a constructor with parameters, it must also have corresponding incoming parameters when listing the enumeration values

1.1, Custom Enumeration Class

1. Steps to customize the enumeration class:

  • 1. Declare the properties of the Season object: private final modifiers
  • 2. Privateize the constructor of the class and assign values to the object properties (if the constructor is not privateized, you can arbitrarily adjust outside, you don't know how many objects there are)
  • 3. Provide multiple objects for the current enumeration class: public static final's
  • 4. Other requirements: such as getting properties of enumerated class objects, providing toString()
public class SeasonTest {
    public static void main(String[] args) {
        Season spring = Season.SPRING;//Class. Static variable (SPRING), which assigns the resulting variable to a spring of Season type
        System.out.println(spring);
    }
}


//Custom Enumeration Class
class Season{

    //1. Declare the properties of the Season object: private final modifiers
    private final String seasonName;
    private final String seasonDesc;

    //2. Privateize the constructor of the class and assign values to the object properties (if the constructor is not privateized, you can arbitrarily adjust outside, you don't know how many objects there are)
    private Season(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //3. Provide multiple objects for the current enumeration class: public static final's
    public static final Season SPRING = new Season("spring","Resuscitation");
    public static final Season SUMMER = new Season("summer","Sunburn");
    public static final Season AUTUMN = new Season("Autumn","Bright autumn");
    public static final Season WINTER = new Season("winter","Snow gleams white");

    //4. Other claim 1: Get properties of enumerated class objects
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    //4. Other claim 2: Provide toString()
    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}

1.2. Use enum keyword to define enumeration class

1. Instructions for use

  • Enumeration classes defined with enum inherit the java.lang.Enum class by default, so they can no longer inherit other classes
  • Enumeration class constructors can only use private permission modifiers
  • All instances of an enumerated class must be explicitly listed in the enumerated class (, separated; terminated). Listed instance systems automatically add public static final modifiers
  • Enumerated class objects must be declared on the first line of an enumerated class

2.JDK 1.5 can use the object of Enum-defined enumeration class as expression in switch expression, and the case clause can use the name of the enumeration value directly without adding enumeration class as qualification. p 503

/**
 * Use enum keyword to define enumeration class
 * Description: Defined enumeration classes inherit by default from java.lang.Enum classes
 */
public class SeasonTest1 {
    public static void main(String[] args) {
        Season1 summer = Season1.SUMMER;

        System.out.println(summer.toString());//SUMMER, the output is the object's name because its parent overrides toString()

        System.out.println(Season1.class.getSuperclass());//Output Season1's parent class
    }
}

//Use enum keyword to define enumeration class
enum Season1{

    //1. Provide objects of the current enumeration class, with "," separating multiple objects, ending with ";"
    SPRING("spring","Resuscitation"),
    SUMMER("summer","Sunburn"),
    AUTUMN("Autumn","Bright autumn"),
    WINTER("winter","Snow gleams white");

    //2. Declare the properties of the Season object: private final modifiers
    private final String seasonName;
    private final String seasonDesc;

    //3. Private class constructors and assign values to object properties
    private Season1(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //4. Other claim 1: Get properties of enumerated class objects
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    //4. Other claim 2: Provide toString()
//    @Override
//    public String toString() {
//        return "Season{" +
//                "seasonName='" + seasonName + '\'' +
//                ", seasonDesc='" + seasonDesc + '\'' +
//                '}';
//    }
}

1.3. Common methods in Enum classes

1. Common methods of Enum classes:

  • toString(): Returns the name of the current enumeration class object
  • values() method: Returns an array of all enumerated class objects. This method makes it easy to iterate through all the enumerated values.
  • valueOf(String str): A string can be converted to the corresponding enumeration class object. Requires that the string must be the Name of an enumerated class object. If not, there will be a runtime exception: IllegalArgumentException.
public class SeasonTest1 {
    public static void main(String[] args) {
        Season1 summer = Season1.SUMMER;//Class. Static variable (SUMMER), which assigns the resulting variable to summer of type Season1

        //1. Method 1: toString():
        System.out.println(summer.toString());


        //2. Method 2:values(): Returns an array of all enumerated class objects
        Season1[] values = Season1.values();

        for(int i = 0;i < values.length;i++){
            System.out.println(values[i]);
        }

        System.out.println("*************************");

        //The state state state of a thread is an enumeration class. State is an internal class of the Thread class
        Thread.State[] values1 = Thread.State.values();
        for(int i = 0;i < values1.length;i++){
            System.out.println(values1[i]);
        }

        //3. Method 3: valueOf(String objName): Returns an object whose object name is objName in an enumeration class.
        Season1 winter = Season1.valueOf("WINTER");

        //If there is no objName enumeration class object, throw an exception: IllegalArgumentException
//        Season1 winter1 = Season1.valueOf("WINTER1");
        System.out.println(winter);

    }
}

//Enumerate classes using enum keyword
enum Season1{
    //1. Provide objects of the current enumeration class, with "," separating multiple objects, ending with ";"
    SPRING("spring","Resuscitation"),
    SUMMER("summer","Sunburn"),
    AUTUMN("Autumn","Bright autumn"),
    WINTER("winter","Snow gleams white");

    //2. Declare the properties of the Season object: private final modifiers
    private final String seasonName;
    private final String seasonDesc;

    //3. Private class constructors and assign values to object properties
    private Season1(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //4. Other claim 1: Get properties of enumerated class objects
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    //4. Other claim 2: Provide toString()
//    @Override
//    public String toString() {
//        return "Season{" +
//                "seasonName='" + seasonName + '\'' +
//                ", seasonDesc='" + seasonDesc + '\'' +
//                '}';
//    }
}

1.4. Implement interfaces using enum classes defined by the enum keyword

1. Scenario 1: Implement the interface and implement the abstract method in the enum class (just like a normal class implements the interface)

2. Scenario 2: Let objects of enumeration classes implement abstract methods in interfaces separately

public class SeasonTest1 {
    public static void main(String[] args) {
        //values(): Returns an array of all enumerated class objects
        Season1[] values = Season1.values();
        for(int i = 0;i < values.length;i++){
            values[i].show(); //Where does spring not come back in Ningxia autumn About winter (line breaks in the middle)
        }

        //valueOf(String objName): Returns an object whose object name is objName in an enumeration class.
        Season1 winter = Season1.valueOf("WINTER");
        winter.show();//Around winter

    }
}

interface Info{
    void show();
}

//Enumerate classes using enum keyword
enum Season1 implements Info{
    //1. Provide objects of the current enumeration class, with "," separating multiple objects, ending with ";"
    SPRING("spring","Resuscitation"){
        @Override
        public void show() {
            System.out.println("Where is spring?");
        }
    },
    SUMMER("summer","Sunburn"){
        @Override
        public void show() {
            System.out.println("Ningxia");
        }
    },
    AUTUMN("Autumn","Bright autumn"){
        @Override
        public void show() {
            System.out.println("Don't come back in autumn");
        }
    },
    WINTER("winter","Snow gleams white"){
        @Override
        public void show() {
            System.out.println("Around winter");
        }
    };

    //2. Declare the properties of the Season object: private final modifiers
    private final String seasonName;
    private final String seasonDesc;

    //3. Private class constructors and assign values to object properties
    private Season1(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //4. Other claim 1: Get properties of enumerated class objects
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

//    @Override
//    public void show() {
//        System.out.println("This is a season");
//    }
}

02. Annotation

2.1. Annotation Overview

1. Since JDK 5.0, Java has added support for metadata, known as Annotation.

2.Annotation is actually a special tag in your code that can be read at compile, class load, run time, and processed accordingly. Using Annotation, programmers can embed additional information in their source files without changing their logic. Code analysis tools, development tools, and deployment tools can be validated or deployed with this supplementary information.

3.Annotation can be used like modifiers to modify the declaration of packages, classes, constructors, methods, member variables, parameters, and local variables, which are stored in Annotation's "name=value" pair.

4. In JavaSE, annotations are used for simple purposes, such as marking out obsolete functionality, ignoring warnings, and so on. Annotations play a more important role in JavaEE/Android, such as configuring any aspect of the application, replacing the redundant code and XML configuration left behind in older versions of JavaEE.

5. Future development models are based on annotations, JPA is based on annotations, Spring 2.5 and above are based on annotations, Hibernate 3.x is also based on annotations, now Struts2 is based on annotations, annotations are a trend, to some extent: Frame = annotation + reflection + design mode.

6. Obtaining annotation information through reflection - Systematic explanation when reflecting content

2.2. Example use of Annotation

1. When using Annotation, add the @ sign in front of it and use it as a modifier. Used to decorate the program elements it supports

2. Example 1: Generate documentation-related annotations

  • @author identifies the author who developed the module, used by multiple authors, split
  • @version indicates the version of this type of module
  • @see Reference Turn, a related topic
  • From which version @since started to increase
  • @param   An explanation of a parameter in a method that cannot be written without a parameter
  • @return specifies the return value of a method, which cannot be written if the return value type of the method is void
  • @exception describes exceptions that may be thrown by a method and cannot be written without an exception explicitly throws by the method
  • Be careful:
    • The @param @return and @exception tags are all method-only.
    • Requirements for @param format: @param parameter name Parameter type Description
    • Format requirements for @return: @return return return return type return value description
    • Format requirements for @exception: @exception exception type exception description
    • @param and @exception can be side-by-side multiple

3. Example 2: Format checking at compile time (three basic notes built into JDK)

  • @Override: Restricts the override of parent methods, this comment can only be used for methods
  • @Deprecated: Used to indicate that the decorated elements (classes, methods, constructors, attributes, etc.) are obsolete. Usually because the structure being modified is dangerous or there is a better choice
  • @SuppressWarnings: Suppress compiler warnings

4. Example 3: Tracking code dependencies to achieve alternative profile functionality

  • Servlet3.0 provides annotations that make it unnecessary to deploy Servlets in a web.xml file.
  • Management of Transactions in the spring Framework
import java.util.ArrayList;
import java.util.Date;

/**
 * Use of Notes
 *
 * 1. Annocation Example usage
 *  Example 1: Generate documentation-related annotations
 *  Example 2: Format checking at compile time (three basic notes built into JDK)
 *      @Override: Limit override of parent method, this comment can only be used for methods
 *      @Deprecated: The elements (classes, methods, etc.) used to represent the modification are obsolete. Usually because the structure being modified is dangerous or there is a better choice
 *      @SuppressWarnings: Suppress compiler warnings
 *
 *  Example 3: Tracking code dependencies to achieve alternative profile functionality
 */
public class AnnotationTest {
    public static void main(String[] args) {
        Person p = new Student();
        p.walk();

        Date date = new Date(2020, 10, 11);//Obsolete, but still usable (for compatibility with previous projects)
        System.out.println(date);

        @SuppressWarnings("unused")//unused, meaning num is not used
        int num = 10;

        @SuppressWarnings({ "unused", "rawtypes" })//rawtypes are generic when declared on behalf of the ArrayList class, but not when instantiated
        ArrayList list = new ArrayList();
    }
}

class Person{
    private String name;
    private int age;

    public Person() {
        super();
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void walk(){
        System.out.println("Man Walking");
    }
    
}

interface Info{
    void show();
}

class Student extends Person implements Info{

    @Override
    public void walk() {
        System.out.println("Student Walking");
    }

    @Override
    public void show() {

    }
}

2.3. How to customize notes

1. How to customize notes: refer to the @SuppressWarnings definition

  •  ① The comment is declared as:@interface
    
  •  ② Internally defined members, usually used value Express
    
  •  ③ You can specify the default values for members, using default Definition
    
  •  ④ If the custom comment has no members, it is an identifying role.
    

2. Instructions:

  •  If the comment has members, when using the comment,<font color='red'>The value of the member needs to be specified</font>. 
    
  •  Custom annotations must be accompanied by an annotated information processing process(Use reflection)Only meaningful.
    
  •  Custom Notes<font color='red'>Both metanotes are indicated by pass</font>: Retention,Target
    
//MyAnnotation Note:

public @interface MyAnnotation {

    String value(); //value is an attribute, not a method
    //String value() default "hello"; // Specify an initial value for Annotation member variables when they are defined (using the default keyword)
}



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


//AnnotationTest class:
 
public class AnnotationTest {
    public static void main(String[] args) {
    
    }
}

//Use of custom annotations: can be placed on top of classes
@MyAnnotation(value = "hello")
class Person{
    
}

Use of 4 basic metanotes in 2.4 and jdk

1. Meta Annotation: Notes explaining existing notes

1.JDK's meta-Annotation is used to modify other Annotation definitions

2.JDK5.0 provides four standard meta-annotation types:

  • Retention
  • Target
  • Documented
  • Inherited

3. Understanding metadata: Data that modifies existing data is called metadata. For example: String name = "atguigu";

  • "Atguigu" is real data. String and name can be thought of as modifications to "atguigu". String represents the type of data. Name gives the data a name
  • To some extent, if you think of "atguigu" as data, you can think of String and name as metadata

2. Specifically introduce @Retention:

1.@Retention: Can only be used to modify an Annotation definition to specify the life cycle of the Annotation, @Rentention contains a member variable of type RetentionPolicy that must be assigned a value when using @Rentention:

  • RetentionPolicy.SOURCE: Valid in source file (i.e. source file retention), the compiler discards comments for this policy directly
  • RetentionPolicy.CLASS: Valid in the class file (that is, class preservation), and JVM does not retain annotations when running Java programs. (This is the default value)
  • RetentionPolicy.RUNTIME: Valid at runtime (runtime retention), and JVM retains comments when running Java programs. The program can get this comment through reflection.

2.@Retention: Specifies the life cycle of the modified Annotation: SOURCE, CLASS (default behavior), RUNTIME

  • Only comments declared as RUNTIME life cycle can be obtained through reflection.

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * @author bai
 * @create 2021-10-31-9:29
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    
    String value();
}

3. Specifically introduce @Target:

1.@Target: Used to modify the Annotation definition to specify which program elements can be modified by the modified Annotation. @ Target also contains a member variable named value.

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;


//@Target indicates that the comment it modifies modifies these structures inside {}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String value();
}

The remaining two metanotes @Documented, @Inherited occur less frequently

4. Specifically introduce @Documented:

1.@Documented: Used to specify that the Annotation class decorated with this meta-Annotation will be extracted into a document by the javadoc tool. By default, javadoc does not include annotations.

  • Annotations defined as Documented must have a Retention value of RUNTIME set.

2.@Documented: Indicates that the modified annotation is preserved when parsed by javadoc. (e.g. note @Deprecated)

5. Specifically introduce @Inherited:

1.@Inherited: The Annotation modified by it will be inheritable. If a class uses Annotation modified by @Inherited, its subclasses will automatically have this annotation.

  • For example, if a custom annotation labeled with the @Inherited annotation is labeled at the class level, the subclass can inherit the parent class level annotation
  • Less used in practical applications
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;

//@Inherited indicates that the annotations it modifies are inheritable
@Inherited
//@Target indicates that the annotation it modifies modifies these structures inside {}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String value();
}



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

    
//@Inherited indicates that the annotations it modifies are inheritable, for example:

//Use of custom annotations: can be placed on top of classes
@MyAnnotation(value = "hello")
class Person{
    
}  

class Student extends Person{ //The child class Student inherits the parent class's comment: @MyAnnotation(value = "hello")
    
}

2.5. Obtaining annotation information from reflection

1. Overview

  • JDK 5.0 adds the AnnotatedElement interface under the java.lang.reflect package, which represents annotated program elements that can be accepted in programs.
  • When an Annotation type is defined as a Runtime Annotation, the annotation is visible at runtime, and the Annotation saved in the class file is read by the virtual machine when the class file is loaded
  • Programs can access Annotation information by calling the following methods on the AnnotatedElement object

2. How to get annotation information: get, call through reflection

  • Prerequisite: Require the Life Cycle States declared in the meta-annotation Retention of this note to be: RUNTIME

2.6, new features of jdk8

Java 8 provides two improvements to annotation processing: repeatable annotations and annotations that can be used for types. In addition, reflection has been enhanced to give the name of the method parameter in Java8. This simplifies the annotations labeled on the method parameters.

2.6.1, new jdk8 features: repeatable annotations

  • (1) Declare @Repeatable on MyAnnotation with a membership value of MyAnnotations.class
  • MyAnnotation's @Target, @Retention, @Inherited meta-annotations are the same as MyAnnotations.

Repeatable annotations implemented prior to 1.jdk8:

//MyAnnotation Note:

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;


@Inherited
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value();
}

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

//MyAnnotations Note:

public @interface MyAnnotations {
    MyAnnotation[] value();
}  

------------------------------------------------------------------------------------------
    
//AnnotationTest class:
 
public class AnnotationTest {
    public static void main(String[] args) {
    
    }
}
    
@MyAnnotations({@MyAnnotation(value="hi"), @MyAnnotation(value="hello")})  //Use of custom notes
class Person{
    
}

Repeatable notes in 2.jdk8:

//MyAnnotation Note:

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;


@Repeatable(MyAnnotations.class)
@Inherited
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value();
}


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

    
//MyAnnotations Note:
   
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;


@Inherited
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotations {
    MyAnnotation[] value();
}
    

------------------------------------------------------------------------------------------
    
//AnnotationTest class:

public class AnnotationTest {
    public static void main(String[] args) {
    
    }
}
    
@MyAnnotation(value="hi")   //Repeatable Notes
@MyAnnotation(value="hello")  
class Person{
    
}

2.6.2, new jdk8 features: type annotations

After 1.JDK1.8, there are two more ElementType enumeration values for the parameter type of metaannotation @Target: TYPE_PARAMETER, TYPE_USE

2. Before Java8, annotations could only be used where they were declared. Starting with Java8, annotations could be applied anywhere.

  • ElementType.TYPE_PARAMETER: Indicates that the comment can be written in a declaration statement for a type variable (for example, a generic declaration).
  • ElementType.TYPE_USE: Indicates that the comment can be written in any statement of type usage.
//MyAnnotation Note:

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;


@Inherited
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, TYPE_PARAMETER, TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default  "hi";
}


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

    
//AnnotationTest class:

public class AnnotationTest {
    public static void main(String[] args) {
    
    }
}
    
//1.TYPE_PARAMETER: Decorate generic types with annotations
class Generic<@MyAnnotation T>{

    //2.TYPE_USE: Indicates that the comment can be written in any statement of type usage
    public void show() throws @MyAnnotation RuntimeException{
        ArrayList<@MyAnnotation String> list  = new ArrayList<>();

        int num = (@MyAnnotation int) 10L;
    }

}

Posted by ade1982 on Tue, 23 Nov 2021 10:33:50 -0800