java基础——枚举类与注解——20200613

本文详细介绍了Java中的枚举类,包括自定义枚举类、使用enum关键字定义枚举类以及Enum类中的常用方法。同时,文章深入探讨了Java的注解Annotation,包括其概述、基本注解的使用、自定义注解以及JDK中的元注解,并讨论了JDK8中注解的新特性,如可重复注解和类型注解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

尚硅谷_Java零基础教程-java入门必备-初学者基从入门到精通全套完整版(宋红康主讲)
P498

枚举类

  • 类的对象只有有限个,确定的。
    • 星期、性别、状态
  • 当需要定义一组常量时,强烈建议使用枚举类。

自定义枚举类

  1. 声明Season对象的属性:private final修饰
  2. 私有化类的构造器,并给对象属性赋值
  3. 提供当前枚举类的多个对象,public static final的
  4. 其他需求:get属性、toString()
class Season {
    public final static Season SPRING = new Season("spring",3,5);
    public final static Season SUMMER = new Season("summer",6,8);
    public final static Season AUTUMN = new Season("autumn",9,11);
    public final static Season WINTER = new Season("winter",12,2);


    private final String name;
    private final int begMonth;
    private final int endMonth;

     private Season(String name, int begMonth, int endMonth) {
        this.name = name;
        this.begMonth = begMonth;
        this.endMonth = endMonth;
    }

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

enum关键字定义枚举类

jdk5之后,可以使用enum关键字定义枚举类

enum NewSeason {
    SPRING("spring",3,5),
    SUMMER("summer",6,8),
    AUTUMN("autumn",9,11),
    WINTER("winter",12,2);


    private final String name;
    private final int begMonth;
    private final int endMonth;

    private NewSeason(String name, int begMonth, int endMonth) {
        this.name = name;
        this.begMonth = begMonth;
        this.endMonth = endMonth;
    }


}

不重写toString()的情况下,

SPRING
SUMMER
AUTUMN
WINTER

Enum类中的常用方法

values()方法:

NewSeason[] values = NewSeason.values();

结果同样是

SPRING
SUMMER
AUTUMN
WINTER
System.out.println(NewSeason.valueOf("WINTER"));
//WINTER

可以在枚举对象里面重写方法:

enum NewSeason implements Info {
    SPRING("spring",3,5){
        @Override
        public void show() {
            System.out.println("spring spring");
        }
    },
    SUMMER("summer",6,8),
    AUTUMN("autumn",9,11),
    WINTER("winter",12,2);

注解Annotation

概述

  • 从jdk5.0开始,java增加了对元数据的支持,也就是Annotation。
  • Annotation其实就是代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过使用Annotation,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或部署。
  • Annotation可以像修饰符一样被使用,可用于修饰包,类,构造器,方法,成员变量,参数,局部变量的声明,这些信息被保存在Annotation的“name=value”对中。
  • 在javaSE中注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在javaEE/Android中注解占据了更重要 的角色,例如用来配置应用程序的任何切面,代替javaEE旧版中所遗留的繁冗代码和XML配置等。
  • 未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的structs2有一部分也是基于注解的了,注解是一种趋势,一定程度上可以说:框架=注解+反射+设计模式。

注解示例

生成文档相关的注解

  • @author:作者
  • @version:版本
  • @see:相关主题
  • @since:从哪个版本开始增加的
  • @param:对方法中某参数的说明
  • @return:对方法返回值的说明
  • @exception:对可能抛出的异常进行说明

在编译时进行格式检查(JDK内置的三个基本注解)

  • @Override:限定重写父类方法,只能用于方法
  • @Deprecated:已过时
  • @SuppressWarnings:抑制编译器警告

跟踪代码依赖性,实现替代配置文件功能

  • Servlet3.0提供了注解 @WebServlet("/login")
  • Spring框架关于事务的管理@Transactional

三个基本注解的使用

校验:不是重写方法的话,@Override会提示

@Override
    public void wa1k() {
        System.out.println("student walk");
    }

@Deprecated会标注在过时的代码上。

不加的话,没有使用的变量是灰色的,加了之后就不会变灰

@SuppressWarnings("unused")
        int age;

自定义注解

参照 @SuppressWarnings

  • 定义新的Annotation类型使用@interface关键字
  • 自定义注解自动继承了java.lang.annotation.Annotation接口
  • Annotation的成员变量在Annotation定义中以无参数方法的形式来声明。其方法名和返回值定义了该成员的名字和类型。我们称为配置参数。类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、以及以上所有类型的数组。
  • 可以在定义Annotation的成员变量时为其指定初始值,指定成员变量的初始值可使用default关键字。
  • 如果只有一个参数成员,建议使用参数名为value
  • 如果定义的注解含有配置参数,那么使用时必须指定参数值,除非它有默认值。格式是“参数名=参数值”,如果只有一个参数成员,且名称为value,可以省略“value=”
  • 没有成员定义的Annotation称为标记;含有成员变量的Annotation称为元数据Annotation
  • 注意:自定义注解必须配上注解的信息处理流程才有意义
public @interface MyAnnotation {
    String value() default "hello";
}

SuppressWarnings :

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is <i>not</i> an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     * <p> The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value();
}

JDK中的元注解

  • JDK的元注解用于修饰其它注解定义
  • JDK5.0提供了4个标准的元注解类型,分别是:
    • Retention
    • Target
    • Documented
    • Inherited
  • 自定义注解通常都会指明Retention和Target
  • @Retention:只能用于修饰一个Annotation,用于指定该Annotation的生命周期,包含一个RetentionPolicy类型的成员变量,使用时必须为该value成员变量指定值:
    • RetentionPolicy.SOURCE:在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释
    • RetentionPolicy.CLASS:在class文件中有效(即class保留),当运行java程序时,JVM不会保留注释,这是默认值
    • RetentionPolicy.RUNTIME:在运行时有效(即运行时保留),当运行Java程序时,JVM会保留注释。程序可以通过反射获取该注释。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}
public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}
  • @Target:用于修饰Annotation定义,用于指定被修饰的Annotation能用于修饰那些程序元素。@Target也包含一个名为value的成员变量。
    • CONSTRUCTOR :用于描述构造器
    • FIELD :用于描述域
    • LOCAL_VARIABLE :用于描述局部变量
    • METHOD:用于描述方法
    • PACKAGE :用于描述包
    • PARAMETER :用于描述参数
    • TYPE : 用于描述类、接口(包括注解类型)或enum声明
@Documented
@Retention(RetentionPolicy.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();
}
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,

    /**
     * Module declaration.
     *
     * @since 9
     */
    MODULE
}

  • @Documented :用于指定被该元注解修饰的Annotation类将被javadoc工具提取成文档。默认情况下,javadoc是不包括注解的。
    • 定义为@Documented的注解必须设置Retention值为RUNTIME。

Deprecated 有 @Documented 标识,在生成文档时,会把被Deprecated 修饰的 提取出来。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
public @interface Deprecated {
    /**
     * Returns the version in which the annotated element became deprecated.
     * The version string is in the same format and namespace as the value of
     * the {@code @since} javadoc tag. The default value is the empty
     * string.
     *
     * @return the version string
     * @since 9
     */
    String since() default "";

    /**
     * Indicates whether the annotated element is subject to removal in a
     * future version. The default value is {@code false}.
     *
     * @return whether the element is subject to removal
     * @since 9
     */
    boolean forRemoval() default false;
}
  • @Inherited:被它修饰的Annotation将具有继承性。如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解。
    • 比如:如果把标有@Inherited注解的自定义 的注解标注在类级别上,子类则可以继承父类类级别的注解。
    • 实际应用中,使用较少。

通过反射获取注解

Student是Person的子类,Person被@MyAnnotation(value = “world”)修饰。

  • 若@MyAnnotation有@Inherited,两个类都有注解。
  • 若@MyAnnotation没有@Inherited,则Student类没有注解。
//通过反射获取注解信息
    @Test
    public void testGetAnnotation(){
        Class<Student> studentClass = Student.class;
        Annotation[] annotations = studentClass.getAnnotations();

        for (Annotation a:annotations          ) {
            System.out.println(a);
        }
        for (Annotation a:Person.class.getAnnotations()          ) {
            System.out.println(a);
        }
    }

JDK8中注解的新特性

可重复注解

  • jdk8之前的写法
@MyAnnotations({@MyAnnotation(value = "yes"),@MyAnnotation(value = "ok")})
public @interface MyAnnotations {
    MyAnnotation[] value();
}
  • jdk8之后的写法
@MyAnnotation(value = "yes")
@MyAnnotation(value = "ok")

声明@Repeatable

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

注意:两个注解的@Target、@Retention、@Inherited等元注解需一致。

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

类型注解

  • jdk8之后,关于元注解@Target的参数类型ElementType枚举值多了两个:TYPE_PARAMETER , TYPE_USE 。
  • 在jdk8之前,注解只能是在声明的地方所使用,java8开始,注解可以应用在任何地方。
    • ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)
    • ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。

修饰泛型:

class Generic< @MyAnnotation T>{
    public void show(){
        ArrayList<@MyAnnotation String> list = new ArrayList<>();
        int num = (@MyAnnotation int) 10L;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值