Java enums and annotations

first look at a demand

It is required to create a Season object, please design and complete it.

class Season{
    
    //类
    private String name;
    private String desc;//描述
    //构造器
    //getXX
    //setXX
}

For seasons only, his objects (specific values) are fixed at four, and there will be no more. The general class design idea cannot reflect the four fixed objects of the season. Use enumeration class.

  • The value of the season is a limited number of values ​​(spring, summer, autumn, winter)
  • Read-only, no modification required.

Because the following conditions cannot exist:

autumn.setName("XXX"); // 修改了秋天的名字

enumerate

  1. Enumeration corresponds to English (enumeration, abbreviated enum)
  2. An enumeration is a collection of constants.
  3. It can be understood here: enumeration belongs to a special class, which only contains a limited set of specific objects.

Two implementations of enumeration

  1. Custom class implements enumeration
  2. Enumerations are implemented using the enum keyword

Custom class implements enumeration - application case

1. There is no need to provide setXxx methods, because enumeration object values ​​are usually read-only.

2. Use final + static to decorate enumeration objects/attributes together to achieve bottom-level optimization. (The combination of final and static can not lead to class loading, which is more efficient)

3. Enumeration object names usually use all uppercase, constant naming conventions.

4. The enumeration object can also have multiple attributes as needed

package com.hspedu.enum_;

public class Enumeration02 {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(Season.AUTUMN);
        System.out.println(Season.SPRING);
    }
}

//演示字定义枚举实现
class Season {
    
    //类
    private String name;
    private String desc;//描述

    //定义了四个对象, 固定.
    public static final Season SPRING = new Season("春天", "温暖");
    public static final Season WINTER = new Season("冬天", "寒冷");
    public static final Season AUTUMN = new Season("秋天", "凉爽");
    public static final Season SUMMER = new Season("夏天", "炎热");


    //1. 将构造器私有化,目的防止 直接 new
    //2. 去掉setXxx方法, 防止属性被修改
    //3. 在Season 内部,直接创建固定的对象
    //4. 优化,可以加入 final 修饰符(static会导致类加载,防止这种情况, final 和 static 搭配使用可以不导致类加载,效率更高)
    private Season(String name, String desc) {
    
    
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
    
    
        return name;
    }

    public String getDesc() {
    
    
        return desc;
    }

    @Override
    public String toString() {
    
    
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

summary:

  1. constructor privatization
  2. This class internally creates a group of objects [four spring, summer, autumn and winter]
  3. Expose the object externally (by adding public final static modifier to the object)
  4. You can provide a get method, but do not provide a set

The enum keyword implements enumeration - a quick start

package com.hspedu.enum_;

public class Enumeration03 {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(Season2.AUTUMN);
        System.out.println(Season2.SUMMER);
    }
}
//演示使用enum关键字来实现枚举类
enum  Season2 {
    
    //类


    //定义了四个对象, 固定.
//    public static final Season SPRING = new Season("春天", "温暖");
//    public static final Season WINTER = new Season("冬天", "寒冷");
//    public static final Season AUTUMN = new Season("秋天", "凉爽");
//    public static final Season SUMMER = new Season("夏天", "炎热");
    //如果使用了enum 来实现枚举类
    //1. 使用关键字 enum 替代 class
    //2. public static final Season SPRING = new Season("春天", "温暖") 直接使用
    //   SPRING("春天", "温暖") 解读 常量名(实参列表)
    //3. 如果有多个常量(对象), 使用 ,号间隔即可
    //4. 如果使用enum 来实现枚举,要求将定义常量对象,写在前面
    //5. 如果我们使用的是无参构造器,创建常量对象,则可以省略 ()
    SPRING("春天", "温暖"), WINTER("冬天", "寒冷"), AUTUMN("秋天", "凉爽"),
    SUMMER("夏天", "炎热"), What();

    private String name;
    private String desc;//描述

    private Season2() {
    
    //无参构造器

    }

    private Season2(String name, String desc) {
    
    
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
    
    
        return name;
    }

    public String getDesc() {
    
    
        return desc;
    }

    @Override
    public String toString() {
    
    
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

The enum keyword implements enumeration considerations

  1. When we use the enum keyword to develop an enumeration class, it will inherit the Enum class by default, and it is a final class. Use the javap tool to demonstrate.

  1. The traditional public static final Season2 SPRING = new Season2("spring", "warm"); can be simplified to SPRING("spring", "warm"), where you must know which constructor it calls.

  2. If the enumeration object is created with a no-argument constructor, both the argument list and the parentheses can be omitted.

  3. When there are multiple enumeration objects, use , to space them, and end with a semicolon.

  4. The enumeration object must be placed at the beginning of the line of the enumeration class.

enum common method description

Explanation: When the keyword enum is used, the Enum class will be inherited implicitly, so that we can use the methods related to the Enum class.

Application examples of enum common methods

  1. toString: The Enum class has been rewritten, and it returns the current object name. Subclasses can rewrite this method to return the attribute information of the object.
  2. name: Returns the current object name (constant name), which cannot be overridden in subclasses.
  3. ordinal: returns the position number of the current object, starting from 0 by default.
  4. values: returns all constants in the current enumeration class.
  5. valueOf: Convert a string to an enumeration object, requiring the string to be an existing constant name, otherwise an exception will be reported!
  6. compareTo: Compare two enumeration constants, the comparison is the number (before minus and after the number)!
package com.hspedu.enum_;

public class EnumMethod {
    
    
    public static void main(String[] args) {
    
    
        //使用Season2 枚举类,来演示各种方法
        Season2 autumn = Season2.AUTUMN;

        //输出枚举对象的名字
        System.out.println(autumn.name());
        //ordinal() 输出的是该枚举对象的次序/编号,从0开始编号
        //AUTUMN 枚举对象是第三个,因此输出 2
        System.out.println(autumn.ordinal());
        //从反编译可以看出 values方法,返回 Season2[]
        //含有定义的所有枚举对象
        Season2[] values = Season2.values();
        System.out.println("===遍历取出枚举对象(增强for)====");
        for (Season2 season: values) {
    
    //增强for循环
            System.out.println(season);
        }

        //valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常
        //执行流程
        //1. 根据你输入的 "AUTUMN" 到 Season2的枚举对象去查找
        //2. 如果找到了,就返回,如果没有找到,就报错
        Season2 autumn1 = Season2.valueOf("AUTUMN");
        System.out.println("autumn1=" + autumn1);
        System.out.println(autumn == autumn1); // T

        //compareTo:比较两个枚举常量,比较的就是编号
        //1. 就是把 Season2.AUTUMN 枚举对象的编号 和 Season2.SUMMER枚举对象的编号比较
        //2. 看看结果
        /*
        源码:
        public final int compareTo(E o) {

            return self.ordinal - other.ordinal;
        }
        Season2.AUTUMN的编号[2] - Season2.SUMMER的编号[3]
         */
        System.out.println(Season2.AUTUMN.compareTo(Season2.SUMMER));

        //补充了一个增强for
//        int[] nums = {1, 2, 9};
//        //普通的for循环
//        System.out.println("=====普通的for=====");
//        for (int i = 0; i < nums.length; i++) {
    
    
//            System.out.println(nums[i]);
//        }
//        System.out.println("=====增强的for=====");
//        //执行流程是 依次从nums数组中取出数据,赋给i, 如果取出完毕,则退出for
//        for(int i : nums) {
    
    
//            System.out.println("i=" + i);
//        }
    }
}

enum implements the interface

  1. After using the enum keyword, you can no longer inherit other classes, because enum will implicitly inherit Enum, and Java is a single inheritance mechanism .

  2. Enumeration classes, like ordinary classes, can implement interfaces, as follows.

enum 类名 implements 接口1,接口2{
    
    }
package com.hspedu.enum_;

public class EnumDetail {
    
    
    public static void main(String[] args) {
    
    
        Music.CLASSICMUSIC.playing();
    }
}
class A {
    
    

}

//1.使用enum关键字后,就不能再继承其它类了,因为enum会隐式继承Enum,而Java是单继承机制
//enum Season3 extends A {
    
    
//
//}
//2.enum实现的枚举类,仍然是一个类,所以还是可以实现接口的.
interface IPlaying {
    
    
    public void playing();
}
enum Music implements IPlaying {
    
    
    // 枚举类,CLASSICMUSIC相当于一个对象
    CLASSICMUSIC;
    @Override
    public void playing() {
    
    
        System.out.println("播放好听的音乐...");
    }
}

Understanding of annotations

  1. Annotation, also known as metadata, is used to modify and interpret data information such as packages, classes, methods, properties, constructors, and local variables.
  2. Like annotations, annotations do not affect program logic, but annotations can be compiled or run , which is equivalent to supplementary information embedded in the code.
  3. In JavaSE, annotations are used for simple purposes, such as marking obsolete functions, ignoring warnings, etc. Annotations occupy a more important role in JavaEE, for example, to configure any aspect of the application, replacing the cumbersome code and XML configuration left in the old version of java EE.

Basic Annotation introduction

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

Three basic Annotations:

  1. @Override: To limit a method is to override the parent class method, and this annotation can only be used for methods.
  2. @Deprecated: Used to indicate that a certain program element (class, method, etc.) is obsolete.
  3. @SuppressWarnings: Suppress compiler warnings.

Basic Annotation application case

@Override

@Override: To limit a method is to override the parent class method, and this annotation can only be used for methods.

Supplementary explanation: @interface in the source code is not an interface interface, but an annotation class added after jdk5.0, indicating an annotation class.

1. @ OverrideIndicates that the method of overriding the parent class is specified (verified from the compilation level). If the parent class does not have a fly method, an error will be reported.

2. If the @Override annotation is not written, and the parent class still has public void fly, it still constitutes rewriting.

3. @Override can only modify methods , not other classes, packages, attributes, etc.

4. View the @Override annotation source code as @Target(ElementType.METHOD), indicating that only methods can be modified

5. @Target is an annotation that modifies annotations, called meta-annotations.

@Deprecated

@Deprecated: Used to indicate that a program element (class, method, etc.) is obsolete

1. Used to indicate that a program element (class, method, etc.) is obsolete

2. You can modify methods, classes, fields, packages, parameters, etc.

3.@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD,
PACKAGE,PARAMETER. TYPE})

4. The role of @Deprecated can achieve compatibility and transition between old and new versions

@SuppressWarnings

@SuppressWarnings: suppress compiler warnings

  1. unchecked is to ignore unchecked warnings
  2. rawtypes ignores warnings that do not specify generics (warning errors that do not specify generics when passing parameters)
  3. unused is to ignore warning errors that do not use a variable
  4. The program elements that can be modified by @SuppressWarnings are, see @Target
  5. When generating @SupperssWarnings, you don’t need to memorize it, just click the yellow prompt on the left to
    select it (note that you can specify the generated location)

Attribute introduction and description

all, suppress all warnings
boxing, suppress warnings related to encapsulation/disassembly jobs
cast, suppress warnings related to cast jobs
dep-ann, suppress warnings related to deprecation annotations
, suppress warnings related to obsolete
fallthrough, suppress warnings related to The warning related to the omission of break in the switch statement
finally suppresses the warning hiding related to the block that is not returned to finally
, suppresses the warning related to the region variable of the hidden variable
incomplete-switch, suppresses the missing item in the switch statement (enum case) Warnings related to
javadoc, suppress warnings related to javadoc
nls, suppress warnings related to non-nls string literals
null, suppress warnings related to null analysis
rawtypes, suppress warnings related to use of raw types
resource, suppress warnings related to use of Closeable types warnings related to resource
restrictions, suppress warnings related to using deprecated or prohibited references to
serial, suppress warnings related to missing serialVersionUID fields for serializable classes
static-access, suppress warnings related to incorrect static access
static- method, suppresses warnings related to methods that may be declared static
super, suppresses warnings related to replaced methods but does not contain super calls
synthetic-access, suppresses warnings related to unoptimized access to inner classes
sync-override, suppresses warnings about missed synchronization due to replacement of synchronization methods
unchecked, suppresses warnings related to unchecked operations
unqualified-field-access, suppresses warnings related to unqualified field access
unused, suppresses warnings related to unused Warnings about code and disabled code

package com.hspedu.annotation_;

import java.util.ArrayList;
import java.util.List;
@SuppressWarnings({
    
    "rawtypes", "unchecked", "unused"})
public class SuppressWarnings_ {
    
    

    //1. 当我们不希望看到这些警告的时候,可以使用 SuppressWarnings注解来抑制警告信息
    //2. 在{""} 中,可以写入你希望抑制(不显示)警告信息
    //3. 关于SuppressWarnings 作用范围是和你放置的位置相关
    //   比如 @SuppressWarnings放置在 main方法,那么抑制警告的范围就是 main
    //   通常我们可以放置具体的语句, 方法, 类.

    //4.  看看 @SuppressWarnings 源码
    //(1) 放置的位置就是 TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE
    //(2) 该注解类有数组 String[] values() 设置一个数组比如 {"rawtypes", "unchecked", "unused"}
    /*
        @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
            @Retention(RetentionPolicy.SOURCE)
            public @interface SuppressWarnings {

                String[] value();
        }
     */
    public static void main(String[] args) {
    
    
        List list = new ArrayList();
        list.add("jack");
        list.add("tom");
        list.add("mary");
        int i;
        System.out.println(list.get(1));

    }

    public void f1() {
    
    
//        @SuppressWarnings({"rawtypes"})
        List list = new ArrayList();


        list.add("jack");
        list.add("tom");
        list.add("mary");
//        @SuppressWarnings({"unused"})
        int i;
        System.out.println(list.get(1));
    }
}

Meta-Annotation of JDK (meta-annotation)

The meta-Annotation of JDK is used to decorate other Annotation.

Types of meta annotations

  1. Retention //Specify the scope of the annotation, three kinds of SOURCE, CLASS, RUNTIME
  2. Target // specify where annotations can be used
  3. Documented //Specify whether the annotation will be reflected in javadoc
  4. Inherited //The subclass will inherit the parent class annotation

@Retention

It can only be used to modify an Annotation definition to specify how long the Annotation can be retained. @Rention contains a member variable of type RetentionPolicy. When using @Rention, you must specify a value for the value member variable: Three values ​​​​of @Retention

  1. RetentionPolicy.SOURCE: After the compiler uses it, it directly discards the comments of this policy
  2. RetentionPolicy.CLASS: The compiler will record the annotations in the class file. When running a Java program, the JVM will not retain the annotations. It's the default value
  3. RetentionPolicy.RUNTIME: The compiler will record the annotation in the class file. When running the Java program, the JVM will retain the annotation. The program can obtain the annotation through reflection.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE) // 编译器编译时生效,不会写入到class文件中
public @interface Override {
    
    
}

@Target

It is used to modify the definition of Annotation, which is used to specify which program elements the modified Annotation can be used to modify. @Target also contains a member variable named value.

@Documented
@Retention(RetentionPolicy.RUNTIME) // 作用范围RUNTIME
@Target(ElementType.ANNOTATION_TYPE) // 只能修饰注解
public @interface Target {
    
     // 说明它是注解
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value(); // 这里深入源码再看一下ElementType的取值
}
public enum ElementType {
    
    
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@Documented

@Documented: It is used to specify that the Annotation class modified by the meta-Annotation will be extracted into a document by the javadoc tool, that is, the annotation can be seen when the document is generated.

Note: An annotation defined as Documented must set the Retention value to RUNTIME .

@Inherited

Annotation modified by it will have inheritance. If a class uses Annotation modified by @Inherited, its subclasses will automatically have the annotation.


Articles and codes have been archived in [Github warehouse: https://github.com/timerring/java-tutorial] or the public account [AIShareLab] can also be obtained by replying to java .

Guess you like

Origin blog.csdn.net/m0_52316372/article/details/130236996