9.枚举类与注解

news2025/1/12 23:02:05

文章目录

  • 1. 枚举类
    • 1.1 自定义枚举类
    • 1.2 enum关键字定义枚举类
    • 1.3 Enum类主要方法
  • 2. 注解
    • 2.1 注解作用
      • 2.1.1 生成文档相关注解
      • 2.1.2 JDK内置基本注解-在编译时进行格式检查
      • 2.1.3 跟踪代码依赖性,实现替代配置文件功能
    • 2.2 自定义Annotation
    • 2.3 JDK中的元注解
      • 2.3.1 @Retention-注解生命周期
      • 2.3.2 @Target-注解修饰范围
      • 2.3.3 @Docunmented-文档注解
      • 2.3.4 @Inherited-继承性
    • 2.4 利用反射获得注解信息
    • 2.5 JDK8注解新特性

1. 枚举类

枚举类就是一种特殊的类,如下:

  1. 枚举类内部预先定义实例,供外界使用。所以枚举类内部的枚举实例对象声明为public static final
  2. 不允许外界创建枚举类实例。所以构造器私有化

这里回顾下:switch语句支持使用枚举类

只有一个对象的枚举类可以看成是单例模式的特殊实现方式

1.1 自定义枚举类

在早期没有关键字Enum,需要用class模拟枚举类特点

  1. 私有化类的构造器,保证不能在类的外部创建其对象

  2. 枚举类内部创建枚举类的实例对象。声明为:public static final

  3. 枚举类对象如果有实例变量,应该声明为private final,并在私有构造器中初始化

public class Season{
    private final String SEASONNAME;//季节的名称
    private final String SEASONDESC;//季节的描述
    
    private Season(String seasonName,String seasonDesc){
        this.SEASONNAME = seasonName;
        this.SEASONDESC = seasonDesc;
    }
    public static final Season SPRING = new Season("春天", "春暖花开");
    public static final Season SUMMER = new Season("夏天", "夏日炎炎");
    public static final Season AUTUMN = new Season("秋天", "秋高气爽");
    public static final Season WINTER = new Season("冬天", "白雪皑皑");
}

JDK1.5后引入enum关键字便于定义枚举类

1.2 enum关键字定义枚举类

  • 使用 enum 定义的枚举类默认继承了 java.lang.Enum类,因此不能再继承其他类
  • 枚举类的构造器只能使用 private 权限修饰符(和自定义枚举类一样私有构造器,可以不写private了的其实,多余捏)
  • 枚举类所有实例必须在枚举类中第一行显式列出(, 分隔 ; 结尾)。列出的实例系统会自动添加 public static final 修饰(实例对象属性隐藏)
public enum SeasonEnum {
    SPRING("春天", "春风又绿江南岸"),
    SUMMER("夏天", "映日荷花别样红"),
    AUTUMN("秋天", "秋水共长天一色"),
    WINTER("冬天", "窗含西岭千秋雪");
    
    private final String seasonName;
    private final String seasonDesc;

    private SeasonEnum(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }
}

自定义枚举类需要重写toString方法,而enum关键字定义枚举类不需要重写toString方法(Enum类返回枚举类对象的名称)。自定义的枚举类继承Object类,enum关键字继承Enum类

1.3 Enum类主要方法

  1. values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值。
  2. valueOf(String str):返回枚举类中对象名是str的对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常:IllegalArgumentException
  3. toString():返回当前枚举类对象常量的名称
public class SeasonTest1 {
    public static void main(String[] args) {
        Season1 summer = Season1.SUMMER;
        //toString():返回枚举类对象的名称
        System.out.println(summer.toString());

		//System.out.println(Season1.class.getSuperclass());
        System.out.println("****************");
        //values():返回所有的枚举类对象构成的数组
        Season1[] values = Season1.values();
        for(int i = 0;i < values.length;i++){
            System.out.println(values[i]);
            values[i].show();
        }
        System.out.println("****************");
        Thread.State[] values1 = Thread.State.values();
        for (int i = 0; i < values1.length; i++) {
            System.out.println(values1[i]);
        }

        //valueOf(String objName):返回枚举类中对象名是objName的对象。
        Season1 winter = Season1.valueOf("WINTER");
        //如果没有objName的枚举类对象,则抛异常:IllegalArgumentException
		//Season1 winter = Season1.valueOf("WINTER1");
        System.out.println(winter);
        winter.show();
    }
}

enum定义的枚举类和普通的Java类一样,可以实现一个或多个接口。

  • 所有接口方法在所有枚举值中呈现相同形式,则只要在整个枚举类中统一实现该方法即可。
  • 接口方法在不同的枚举值中呈现不同的形式 , 则可以让每个枚举值分别来实现该方法,如下:
//枚举类待实现的接口
interface Info{
    void show();
}

//使用enum关键字枚举类
enum Season1 implements Info{
    //枚举值之间用","隔开,";"结束
    SPRING("春天","春暖花开"){
        @Override
        public void show() {
            System.out.println("春天在哪里?");
        }
    },
    SUMMER("夏天","夏日炎炎"){
        @Override
        public void show() {
            System.out.println("宁夏");
        }
    },
    AUTUMN("秋天","秋高气爽"){
        @Override
        public void show() {
            System.out.println("秋天不回来");
        }
    },
    WINTER("冬天","冰天雪地"){
        @Override
        public void show() {
            System.out.println("大约在冬季");
        }
    };

    //声明Season对象的属性:private final修饰
    private final String seasonName;
    private final String seasonDesc;

    private Season1(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //诉求:获取枚举类对象的属性
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }
}

2. 注解

  • Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理。通过使用 Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署
  • Annotation 可以像修饰符一样被使用, 可用于修饰包,类,构造器,方法,成员变量, 参数,局部变量的声明,这些信息被保存在 Annotation“name=value” 对中
  • 未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是基于注解的了,注解是一种趋势,一定程度上可以说:框架 = 注解 + 反射 + 设计模式
  • 使用 Annotation 时要在其前面增加 @ 符号, 并**把该 Annotation 当成一个修饰符使用。**用于修饰它支持的程序元素

2.1 注解作用

2.1.1 生成文档相关注解

  • @author 标明开发该类模块的作者,多个作者之间使用,分割

  • @version 标明该类模块的版本

  • @see 参考转向,也就是相关主题

  • @since 从哪个版本开始增加的

  • @param 对方法中某参数的说明,如果没有参数就不能写

  • @return 对方法返回值的说明,如果方法的返回值类型是void就不能写

  • @exception 对方法可能抛出的异常进行说明 ,如果方法没有用throws显式抛出的异常就不能写其中

    • @param @return 和 @exception 这三个标记都是只用于方法的。
    • @param的格式要求:@param 形参名 形参类型 形参说明
    • @return 的格式要求:@return 返回值类型 返回值说明
    • @exception的格式要求:@exception 异常类型 异常说明
    • @param和@exception可以并列多个

2.1.2 JDK内置基本注解-在编译时进行格式检查

  • @Override: 限定重写父类方法, 该注解只能用于方法

  • @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择

  • @SuppressWarnings: 抑制编译器警告

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

Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署

2.2 自定义Annotation

  • 定义新的 Annotation 类型使用 @interface关键字(和interface没有关系)

  • 自定义注解自动继承了java.lang.annotation.Annotation接口

  • 注解中以无参数方法的形式来声明成员变量。方法名和返回值对应成员的名字和类型。我们称为配置参数。类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、以上所有类型的数组。

  • 可以使用 default 关键字在定义 Annotation 的成员变量时为其指定初始值

  • 如果只有一个参数成员,建议使用参数名为value

  • 如果定义的注解含有配置参数且没有默认值时,那么使用时必须指定参数值。格式是“参数名 = 参数值” ,如果只有一个参数成员,且名称为value,可以省略“value=”

  • 没有成员定义的 Annotation 称为标记(注解中没有任何配置参数);包含成员变量的 Annotation 称为元数据Annotation

注意:自定义注解必须配上注解的信息处理流程才有意义

@MyAnnotation(value="lalala")
public class MyAnnotationTest {
    public static void main(String[] args) {
        Class clazz = MyAnnotationTest.class;
        Annotation a = clazz.getAnnotation(MyAnnotation.class);
        MyAnnotation m = (MyAnnotation) a;
        String info = m.value();
        System.out.println(info);
    }
}

@interface MyAnnotation{
    String value() default "auguigu";
}

2.3 JDK中的元注解

用于修饰其他注解的注解称为元注解,JDK5.0提供了4个标准的meta-annotation类型,分别是:Retention,Target,Documented,Inherited

2.3.1 @Retention-注解生命周期

只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 的生命周期

@Rentention 包含一个 RetentionPolicy 枚举类型的成员变量,每一个枚举值指代不同的生命周期

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
 /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

使用@Rentention 时必须为该 value 成员变量指定值:

  1. **RetentionPolicy.SOURCE:**在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释

  2. **RetentionPolicy.CLASS:**在class文件中有效(即class保留) , 当运行 Java 程序时, JVM 不会保留注解。 这是默认值

  3. **RetentionPolicy.RUNTIME:**在运行时有效(即运行时保留),当运行 Java 程序时, JVM会保留注释。程序可以通过反射获取该注释

2.3.2 @Target-注解修饰范围

指定被修饰的 Annotation 能用于修饰哪些程序元素。 @Target 也包含一个名为 value 的成员变量。

@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();
}

ElementType源码(ElementType类似Retention的RetentionPolicy)

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
}

2.3.3 @Docunmented-文档注解

被该元注解修饰的注解类将被javadoc 工具提取成文档。默认情况下,javadoc是不包括注解的。

定义为Documented的注解必须设置Retention值为RUNTIME。

2.3.4 @Inherited-继承性

@Inherited(*/*ɪnˈherɪtɪd/): 被它修饰的 Annotation 将具有继承性。如果某个类使用了被@Inherited 修饰的 Annotation,则其子类将自动具有该注解。

比如:如果把标有@Inherited注解的自定义的注解标注在类级别上,子类则可以继承父类类级别的注解

2.4 利用反射获得注解信息

  • JDK 5.0 在 java.lang.reflect 包下新增了 AnnotatedElement 接口, 该接口代表程序中可以接受注解的程序元素

  • 当一个 Annotation 类型被定义为运行时 Annotation 后, 该注解才是运行时可见,。当 class 文件被载入时保存在 class 文件中的 Annotation 才会被虚拟机读取

  • 程序可以调用 AnnotatedElement对象的如下方法来访问 Annotation 信息

    image-20230125004455260

2.5 JDK8注解新特性

  • JDK1.8之后,关于元注解@Target的参数类型ElementType枚举值多了两个:TYPE_PARAMETER,TYPE_USE

  • 在Java 8之前,注解只能是在声明的地方所使用,Java8开始,注解可以应用在任何地方。

    ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)。

    ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。

public class TestTypeDefine<@TypeDefine() U> {
	private U u;
	public <@TypeDefine() T> void test(T t){
	}
}
@Target({ElementType.TYPE_PARAMETER})
@interface TypeDefine{
}
@MyAnnotation
public class AnnotationTest<U> {
    @MyAnnotation
    private String name;
    public static void main(String[] args) {
        AnnotationTest<@MyAnnotation String> t = null;
        int a = (@MyAnnotation int) 2L;
        @MyAnnotation
        int b = 10;
    }
    public static <@MyAnnotation T> void method(T t) {
    }
    public static void test(@MyAnnotation String arg) throws @MyAnnotation Exception {
    }
}
@Target(ElementType.TYPE_USE)
@interface MyAnnotation {
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1579801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python零基础从小白打怪升级中~~~~~~~流程控制语句

第三节&#xff1a;Python的流程控制语法 一、Python条件语句的语法 if 条件1:条件1成立执⾏的代码一条件1成⽴执⾏的代码二...... elif 条件2&#xff1a;条件2成立执⾏的代码三条件2成立执⾏的代码四...... ...... else:以上条件都不成⽴&#xff0c;执行的代码五以上条件都…

海外盲盒系统开发,盲盒出口成为企业新机遇

随着盲盒的兴起&#xff0c;国内消费市场形成了万物皆可盲盒的态势。并且&#xff0c;盲盒自带社交属性&#xff0c;也成为了年轻人的社交神器。 除了在国内&#xff0c;盲盒在海外也掀起了一股热潮&#xff0c;呈现出了爆发式增长形势&#xff0c;国内热门盲盒企业也出口到了…

Redis的三种部署方案

文章目录 单机模式主从复制哨兵模式分片集群 在Redis中提供的集群方案总共有三种&#xff1a;单机模式&#xff0c;主从复制集群、哨兵模式&#xff0c;Redis分片集群 单机模式 Redis 只运行在一台服务器上&#xff0c;并且所有的数据都存储在这一台服务器的内存中。 主从复制…

小程序商城免费搭建之java商城 电子商务Spring Cloud+Spring Boot+二次开发+mybatis+MQ+VR全景

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

黄金白银价格上涨是投资机会吗?

黄金和白银&#xff0c;作为历史悠久的贵重金属&#xff0c;一直以来都被投资者视为避险资产。近年来&#xff0c;随着全球经济环境的变动&#xff0c;我们观察到黄金与白银的价格不断攀升&#xff0c;这是否预示着投资机会的到来&#xff1f;今天&#xff0c;就让我们来深度探…

【保姆级讲解SQL Server的详细使用教程】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

ATG-2021B功率信号源可以应用在哪些方面

功率信号源是一种能够产生一定功率的信号源&#xff0c;广泛应用于各个领域。下面将介绍功率信号源在电子、通信、工业和科研等方面的应用。 在电子行业中&#xff0c;功率信号源是一种重要的测试工具。它可以产生各种波形的信号&#xff0c;如正弦波、方波、脉冲波等&#xff…

vue中实现表格的局部刷新

背景&#xff1a; 列表中展示所有审核任务信息&#xff0c;包括审核状态、审核进度等&#xff0c;原来的实现是【查询】按钮绑定了一个定时器&#xff0c;定时查询整个列表&#xff0c;但是需要用户手动开启 领导觉得这种方式用户体验不好&#xff0c;希望能够实现【审核进度…

Golang | Leetcode Golang题解之第16题最接近的三数之和

题目&#xff1a; 题解&#xff1a; func threeSumClosest(nums []int, target int) int {sort.Ints(nums)var (n len(nums)best math.MaxInt32)// 根据差值的绝对值来更新答案update : func(cur int) {if abs(cur - target) < abs(best - target) {best cur}}// 枚举 a…

人工智能支持节能的七种方式

2024年2月&#xff0c;OpenAI公布了名为“Sora”的人工智能模型。从去年的chatgpt到今天Sora发布&#xff0c;OpenAI的每⼀次重要的动作和发布&#xff0c;都伴随着⼀场场精妙绝伦精巧的事件营销&#xff0c;它的设置议题的能⼒&#xff0c;节奏控制&#xff0c;公众引导堪称创…

P1731 [NOI1999] 生日蛋糕——典型的回溯和剪枝题目,值得一看

今天尝试了一下md的编辑器&#xff0c;不知道有没有什么改变 [NOI1999] 生日蛋糕 题目背景 数据加强版 link 题目描述 7 月 17 日是 Mr.W 的生日&#xff0c;ACM-THU 为此要制作一个体积为 N π N\pi Nπ 的 M M M 层生日蛋糕&#xff0c;每层都是一个圆柱体。 设从下往…

node后端上传文件到本地指定文件夹

实现 第一步&#xff0c;引入依赖 const fs require(fs) const multer require(multer) 第二步&#xff0c;先设置一个上传守卫&#xff0c;用于初步拦截异常请求 /*** 上传守卫* param req* param res* param next*/ function uploadFile (req, res, next) {// dest 值…

GD32F470_(4线制)火光/火焰传感器模块火源探测 红外接收传感器 智能车配件

2.16 火焰传感器 红外火焰传感器可以用来探测火源或其它一些波长在700纳米~1000纳米范围内的热源&#xff0c;在机器人比赛中&#xff0c;远红外火焰探头起到非常重要的作用&#xff0c;它可以用作机器人的眼睛来寻找火源或足球。利用它可以制作灭火机器人等。 红外火焰传感器…

10-热点文章-定时计算

xxl-Job分布式任务调度 1 今日内容 1.1 需求分析 目前实现的思路&#xff1a;从数据库直接按照发布时间倒序查询 问题1&#xff1a; 如何访问量较大&#xff0c;直接查询数据库&#xff0c;压力较大 问题2&#xff1a; 新发布的文章会展示在前面&#xff0c;并不是热点文章 …

R语言数据操纵:常用函数

目录 处理循环的函数 lapply函数 apply函数 mapply函数 tapply函数 split函数 排序的函数 sort函数与order函数 总结数据信息的函数 head函数与tail函数 summary函数 str函数 table函数 any函数 all函数 xtab函数 object.size函数 这篇文章主要介绍R语言中处理…

全网最全的APP测试面试题(含文档)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、基础篇 1、请介绍一下&#xff0c;APP测试流程&#xff1f…

Windows的“上帝模式”

Windows操作系统,以其强大的功能和广泛的兼容性深受全球用户喜爱。然而,随着系统功能的日益丰富,许多深度设置和管理选项可能隐藏在层层菜单之下,不易被普通用户迅速找到。为了简化这一过程,微软在Windows Vista之后的版本中引入了一项鲜为人知但极为实用的功能——“上帝…

鸿蒙千帆起~ 是转?还是留?

近期鸿蒙系统相关行业热度一度高涨&#xff0c;像今天2024年1月18日 鸿蒙OS Next开发者预览版正式发布引起了不少业内人士关注&#xff0c;再度冲上了热榜。余承东老余之前就说过2024年是鸿蒙关键的一年&#xff0c;从这句话就可以看出后一定有大的动作。 就像去年有业内人士网…

【Android】App通信基础架构相关类源码解析

应用通信基础架构相关类源码解析 这里主要对Android App开发时&#xff0c;常用到的一些通信基础类进行一下源码的简单分析&#xff0c;包括&#xff1a; Handler&#xff1a;处理器&#xff0c;与某个Looper&#xff08;一个线程对应一个Looper&#xff09;进行关联。用于接…

自动驾驶中的多目标跟踪_第二篇

自动驾驶中的多目标跟踪:第二篇 上一节介绍了多目标跟踪的定义、应用场景和类型以及面临的挑战&#xff1b;在这一节&#xff0c;我们回顾贝叶斯滤波&#xff0c;简单介绍运动模型和量测模型&#xff0c;卡尔曼滤波等。 附赠自动驾驶学习资料和量产经验&#xff1a;链接 贝叶…