当前位置: 首页 > 图灵资讯 > 技术篇> Java枚举和注解

Java枚举和注解

来源:图灵教育
时间:2023-04-19 16:10:18

  先看需求

  创建季节的要求(Season) 请设计并完成对象。class Season{//类 private String name; private String desc;//描述 //构造器 //getXX //setXX}

  就季节而言,他的对象(具体值)是固定的四个,不会有更多。一般的类设计理念不能反映季节是固定的四个对象。使用枚举类。 季节值是有限的几个值(spring, summer, autumn, winter) 只读,不需要修改。

  因为不能存在以下情况: autumn.setName("XXX"); // 秋天的名字被修改了 枚举 枚举对应英语(enumeration, 简写enum) 枚举是一组常量的集合。 这里可以理解:枚举属于一个特殊类别,只包含一组有限的特定对象。 实现枚举的两种方法 实现自定义类的枚举 使用enum 实现枚举的关键字 自定义类实现枚举-应用案例

  1.setxxx方法不需要提供,因为枚举对象值通常只读.

  2.使用枚举对象/属性 final + 共同修改static,实现底层优化.(final 和 static 搭配使用不会导致类加载,效率更高)

  3.枚举对象名通常使用所有大写和常量命名规范.

  4.枚举对象也可以根据需要有多个属性 package com.hspedu.enum_;public class Enumeration02 { public static void main(String[] args) { System.out.println(Season.AUTUMN); System.out.println(Season.SPRING); }}///演示字定义枚举实现classs 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 + '\'' + '}'; }}

  小结: 私有化结构器 在本类内部创建一组对象[四个 春夏秋冬] 对外暴露对象(通过添加publicic) final static 修饰符) 可提供get 方法,但不要提供set enum 关键词实现枚举-快速入门 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(夏”, "炎热"); ///如果使用enumm 实现枚举类 //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 + '\'' + '}'; }} enum 关键字实现枚举注意事项 当我们使用enum时 默认情况下,当关键字开发一个枚举类时,Enum将被继承 类, 而且是finalal 类,使用 javap 演示工具。

Java枚举和注解_枚举类

传统的public static final Season2 SPRING = new Season2(“春天” "温暖"); 简化为SPRING(“春天”, “温暖”), 必须知道它调用的是哪个结构器。 若使用无参构造器创建枚举对象,则可省略实参列表和小括号。 当有多个枚举对象时,使用,间隔,最后有一个分号结束。 枚举对象必须放在枚举行首。 enum 常用方法说明

  说明:使用关键字enumm Enum将被隐式继承 类, 这样,我们就可以使用Enum 类相关方法。

Java枚举和注解_枚举类_02

enum 常用方法应用实例 toString:Enum 类别已重写,返回当前对象名称,子类可重写该方法,用于返回对象的属性信息。 name:返回当前对象名(常量名),子类不能重写。 ordinal:返回当前对象的位置号,默认从0 开始。 values:返回当前枚举类中的所有常量。 valueOf:将字符串转换为枚举对象,要求字符串必须是现有的常量名,否则会报告异常! compareTo:比较两个枚举的常量编号(前减后编号)! 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 (int i = 0; i < nums.length; i++) {// System.out.println(nums[i]);// }// System.out.println(“=============”);// //执行过程是 从nums数组中依次取出数据,赋给i, 取出后退出for//// for(int i : nums) {// System.out.println("i=" + i);// } }} enum 实现接口 使用enum 在关键字之后,你不能继承其他类别,因为enum Enum将被隐式继承, Java 是单一继承机制。 像普通类一样,枚举类可以实现以下形式的界面。 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 { // 枚举类,CLASICMUSIC相当于对象 CLASSICMUSIC; @Override public void playing() { System.out.println(”播放好听的音乐..."); }} 注解的理解 注解(Annotation)又称元数据(Metadata),用于修改解释包、类、方法、属性、构造器、局部变量等数据信息。 与注释一样,注释不影响程序逻辑,但注释可以编译或操作,相当于嵌入代码中的补充信息。 JavaSE 注释的使用目的相对简单,如标记过时功能、忽略警告等。在JavaEEEE中 注释占据了更重要的角色,比如用来配置应用程序的任何部分,而不是java EE 旧版本中留下的繁琐代码和XML 配置等。 Annotation基本 介绍

  使用Annotation 增加前面的时间 @ 符号, Annotation 作为修饰符使用。用于修改其支持的程序元素。

  三个基本的Annotation: @Override: 限制某种方法,就是重写父类方法, 该注释只能用于方法。 @Deprecated: 用于表示程序元素(类, 方法等)已过时。 @SuppressWarnings: 抑制编译器警告。 Annotation基本 应用案例@Override

  @Override:限制某种方法是重写父类方法,只能用于方法。

  补充说明: 源代码中的@interface不是interface接口,而是在jdk5.0后加入注解类,表示注解类。

  1.@ Override 指定重写父类的方法(从编译层面验证),如果父类没有fly方法,就会报错。

  2.如果不写@override注释,而父亲仍然有publicice void fly,它仍然构成重写。

  3.@Overrride只能修改方法,不能修改其他类别,包、属性等

  4.查看@Overrride注释源代码@Target(ElementType.METHOD), 说明只能修改方法

  5.@Target是修饰注解的注解,称为元注解。@Deprecated

  @Deprecated: 用于表示程序元素(类, 方法等)已过时

  1.表示程序元素(类、方法等)已过时

  2.可修改方法、类别、字段、包、参数等

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

  4.@Deprecated的作用可以兼容和过渡新旧版本@SuppressWarnings

  @SuppressWarnings: 抑制编译器警告 unchecked忽略了未经检查的警告 rawtypes忽略了没有指定泛型的警告(传参时没有指定泛型的警告错误) unused忽略了未使用变量的警告错误 @Supreswarnings可以修改的程序元素是查看@Target 在生成@Suppersswarnings时,可以直接点击左侧的黄色提示进行选择(注意生成的位置) 属性介绍及说明

  all,抑制所有警告boxing、与包装/拆卸操作相关的警告cast、与强制转换操作相关的警告dep-ann,与淘汰注释相关的警告deprecation、与淘汰相关的警告falthrough、与switch陈述中遗漏break相关的警告finally、抑制与未传回finally区块相关的警告hiding,抑制与隐藏变数区域变数相关的警告incompletete-switch,对switch陈述的抑制(enum case)与项目相关的警告javadoc,与javadoc相关的警告nls,与非nls字串相关的警告null,抑制与空值分析相关的警告rawtypes,抑制与使用raw类型相关的警告resource,抑制与使用closeable类型资源相关的警告restriction,抑制和使用不推荐或禁止参考相关的警告rerial,与serialversionUID栏相关的抑制和可序列化类别遗漏的警告staticc-access,与静态访问不正确相关的抑制警告staticc-method,与可能宣布为static的方法相关的警告super,与替换方法相关但不包括super呼叫的警告synthetic-access,与内部类别访问未最佳化相关的抑制警告sync-override,因替换同步方法而遗漏同步警告unchecked,抑制与未检查操作相关的警告unqualified-field-access,抑制与栏存取不合格相关的警告unused,抑制与未使用程式码和停用程式码相关的警告 package com.hspedu.annotation_;import java.util.ArrayList;import java.util.List;@SuppressWarnings({"rawtypes", "unchecked", "unused"})public class SuppressWarnings_ { //1. 当我们不想看到这些警告时,可以使用它们 Suppreswarnings注释抑制警告信息 //2. 在{""} 中间,可以写入你想抑制(不显示)警告信息 //3. 关于SuppressWarningss 功能范围与你放置的位置有关 // 比如 @Suppreswarnings放置在 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)); }} JDK 元Annotation(元注解)

  JDK 元Annotation 用于修饰其他 Annotation。元注释的类型 Retention //指定注释范围,三种SOURCE,CLASS,RUNTIME Target // 哪里可以使用指定的注释? Documented ///指定注释是否为javadoc 体现 Inherited ////子类会继承父类注释 @Retention

  只能用来修饰Annotation 定义, 用于指定Annotation 能保留多长时间, @Rentention 它包含RetentionPolicy类型的成员变量, 使用@Rentention 必须是value 成员变量指定值: @Retention 的三种值 RetentionPolicy.SOURCE: 使用编译器后,直接丢弃该策略的注释 RetentionPolicy.CLASS: 编译器将注释记录在class中 文件中. 运行Java时 程序时, JVM 注释不会保留。这是默认值 RetentionPolicy.RUNTIME:编译器将注释记录在class中 文件中. 运行Java时 程序时, JVM 会保留注解. 该注释可以通过反射获得。

Java枚举和注解_ide_03

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

  用于修饰 Annnotation定义用于指定被修改的Annotation可以修改哪些程序元素.@Target 它还包含一个成员变量,叫做value。 @Documented@Retention(RetentionPolicy.RUNTIME) // RUNTIMEEEE的作用范围@Target(ElementType.ANNOTATION_TYPE) // publicic只能修改 @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:用于指定被该元 Annotation修改的Annotation将被javadoc工具提取成文档,即在生成文档时可以看到注释。

  说明:定义为 Documented 必须设置注释 Retention 值为 RUNTIME。@Inherited

  被它修改的Annnotation将具有继承性。如果一个类别使用被@inherited修改的Annotation,其子类将自动具有该注释。

  文章和代码已归档为[Github仓库:https://github.com/timerring/java-tutorial 】或者公众号【AIShareLab】回复 java 也可获取。