【JavaSE】枚举和注解学习笔记
枚举和注解
-枚举
-
规定多选一数据类型的解决方案-枚举
- 枚举对应英文(enumeration,简写 enum)
2)枚举是一组常量的集合。
3)可以这里理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象。
- 枚举对应英文(enumeration,简写 enum)
-
枚举的两种实现方式
-
自定义实现枚举
-
使用enum关键字实现枚举
-
-
自定义类实现枚举
-
不需要提供setXxx 方法,因为枚举对象值通常为只读.
-
对枚举对象/属性使用 final + static 共同修饰,实现底层优化
-
枚举对象名通常使用全部大写,常量的命名规范
-
枚举对象根据需要,也可以有多个属性
-
-
自定义类实现枚举小结
-
小结:进行自定义类实现枚举,有如下特点:
-
-
构造器私有化
-
本类内部创建一组对象
-
对外暴露对象(通过为对象添加public final static修饰符)
-
可以提供 get方法,但是不要提供 set
-
-
-enum枚举类
-
enum关键字实现枚举注意事项
-
当我们使用enum关键字开发一个枚举类时,默认会继承Enum类,而且是一个final类,用javap(反编译 )工具可以验证
-
传统的public static final Season2 SPRING = new Season2(“春天”,“温暖”);简化成SPRING(“春天”,“温暖”),这里必须知道,它调用的是哪个构造器。
-
如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略
-
当有多个枚举对象时,使用","间隔,最后一个分号结尾
-
枚举对象必须放在枚举类的行首
-
-
enum常用方法说明
说明:使用enum关键字时,会隐式继承Enum类,这样我们就可以使用Enum类相关方法。(看以下源码定义)
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable{}- toString:Enum类已经重写该方法,返回的是当前对象名,子类可以重写该方法,用于返回对象的属性信息
- name:可以返回当前对象名(常量名),子类中不能重写
- oridnal:返回当前对象的位置号,默认从0开始
- values:返回当前枚举类中所有常量
- valuesOf:将字符串转换成枚举对象,要求字符串必须为已有常量名,否则报异常
- compareTo:比较两个枚举常量,比较的就是编号
package com.xijie.enum_;/*** 演示Enum枚举的使用* 记录红绿灯颜色、时间、说明的枚举*/ public enum TrafficLightEnum {//枚举对象,访问权限是私有、类成员、常量,实现了抽象方法GREEN(30,"绿灯代表可以通行"){@Overridepublic String getAction() {return "请通行";}},YELLOW(3,"黄灯代表准备刹车") {@Overridepublic String getAction() {return "请刹车";}},RED(35,"红灯代表禁止通行") {@Overridepublic String getAction() {return "请停车";}};//私有常量成员变量private final int durationTime;private final String info;//私有构造方法TrafficLightEnum(int durationTime, String info) {//信号灯时间this.durationTime = durationTime;this.info = info;}//get方法public int getDurationTime() {return durationTime;}public String getInfo() {return info;}//抽象方法,由枚举对象实现public abstract String getAction(); }package com.xijie.enum_;public class TrafficLightEnumTest {public static void main(String[] args) {//TrafficLightEnum枚举类的基本使用TrafficLightEnum greenLight = TrafficLightEnum.GREEN;TrafficLightEnum greenLight2 = TrafficLightEnum.GREEN;TrafficLightEnum yellowLight = TrafficLightEnum.YELLOW;TrafficLightEnum redLight = TrafficLightEnum.RED;//比较两个绿灯是否相同System.out.println("两个绿灯是否相同:"+(greenLight==greenLight2));//比较红灯和黄灯是否相同System.out.println("红灯和黄灯是否相同:"+(redLight==yellowLight));//访问黄灯的所有成员及自定义方法System.out.println("黄灯的名字叫:"+yellowLight.name());System.out.println("黄灯的意思是:"+yellowLight.getInfo());System.out.println("黄灯亮时应该:"+yellowLight.getAction());//enum方法演示//toString:Enum类已经重写该方法,返回的是当前对象名,子类可以重写该方法,用于返回对象的属性信息System.out.println("绿灯的名字是"+greenLight.toString());System.out.println("黄灯的名字是"+yellowLight.toString());System.out.println("红灯的名字是"+redLight.toString());//name:可以返回当前对象名(常量名),子类中不能重写System.out.println("绿灯的常量名是"+greenLight.name());System.out.println("黄灯的常量名是"+yellowLight.name());System.out.println("红灯的常量名是"+redLight.name());//oridnal:返回当前对象的位置号,默认从0开始System.out.println("绿灯的位置号是"+greenLight.ordinal());System.out.println("黄灯的位置号是"+yellowLight.ordinal());System.out.println("红灯的位置号是"+redLight.ordinal());//values:返回当前枚举类中所有常量TrafficLightEnum[] enums = TrafficLightEnum.values();for(TrafficLightEnum e:enums){System.out.println(e.name());}//valuesOf:将字符串转换成枚举对象,要求字符串必须为已有常量名,否则报异常String redStr="RED";TrafficLightEnum red = TrafficLightEnum.valueOf(redStr);System.out.println("字符串转换为枚举对象:"+red.name());//compareTo:比较两个枚举常量,比较的就是编号System.out.println("比较绿灯和绿灯:"+greenLight.compareTo(greenLight2));System.out.println("比较黄灯和红灯:"+yellowLight.compareTo(redLight));System.out.println("比较红灯和黄灯:"+redLight.compareTo(yellowLight));System.out.println("比较红灯和绿灯:"+redLight.compareTo(greenLight));} } -
一个练习-用三种方法定义枚举常量的别名
package com.xijie.enum_;public enum DayOfWeekEnum {//重写toString方法也可以返回自定义字符串MONDAY("星期一"){@Overridepublic String getChineseNameOfTheDay() {return "星期一";}@Overridepublic String toString() {return "星期一";}},TUESDAY("星期二"){@Overridepublic String getChineseNameOfTheDay() {return "星期二";}@Overridepublic String toString() {return "星期二";}},WEDNESDAY("星期三"){@Overridepublic String getChineseNameOfTheDay() {return "星期三";}@Overridepublic String toString() {return "星期三";}},THURSDAY("星期四"){@Overridepublic String getChineseNameOfTheDay() {return "星期四";}@Overridepublic String toString() {return "星期四";}},FRIDAY("星期五"){@Overridepublic String getChineseNameOfTheDay() {return "星期五";}@Overridepublic String toString() {return "星期五";}},SATURDAY("星期六"){@Overridepublic String getChineseNameOfTheDay() {return "星期六";}@Overridepublic String toString() {return "星期六";}},SUNDAY("星期天"){@Overridepublic String getChineseNameOfTheDay() {return "星期天";}@Overridepublic String toString() {return "星期天";}},;//存储星期日期的中文名称private final String chineseName;DayOfWeekEnum(String chineseName) {this.chineseName=chineseName;}//get方法public String getChineseName() {return chineseName;}//使用抽象方法也可以起到同样的效果public abstract String getChineseNameOfTheDay(); }
package com.xijie.enum_;public class DayOfWeekTest {public static void main(String[] args) {//通过获取枚举对象的成员方法获取自定义星期名称System.out.println("==所有星期的信息如下==");for (DayOfWeekEnum dayEnum : DayOfWeekEnum.values()) {System.out.println(dayEnum.getChineseName());}//通过自定义抽象方法获取自定义星期名称System.out.println("==所有星期的信息如下==");for (DayOfWeekEnum dayEnum : DayOfWeekEnum.values()) {System.out.println(dayEnum.getChineseNameOfTheDay());}//通过重写的toString方法获取自定义星期名称System.out.println("==所有星期的信息如下==");for (DayOfWeekEnum dayEnum : DayOfWeekEnum.values()) {System.out.println(dayEnum);}}
}
-
枚举类的注意事项
1.使用enum关键字后,就不能再继承其他类了,因为enum会隐式继承Enum,而Java是单继承机制
2.枚举类和普通类一样,可以实现接口,如下形式:
enum 类名 implements 接口1, 接口2...{}
-注解
-
注解的理解
- 注解(Annotation)也被称为元数据(Metadata),用于修饰解释包、类、方法、属性、构造器、局部变量等数据信息。
- 和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息。
- 在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替javaEE旧版中所遗留的繁冗代码和XML配置等。
-
基本的Annotation介绍
使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符使用。用于修饰它支持的程序元素
- 三个基本的Annotation
- @Override:限定某个方法,是重写父类方法,该注解只能用于方法
- @Deprecated:用于表示某个程序元素(类,方法等)已经过时
- @SuppressWarnings:抑制编译器警告
- 三个基本的Annotation
-
@Override简介
- @Override限定某个方法是重写了父类方法,该注解只能用于方法,不能修饰类、包、属性等
- @Override注解写在方法上方
- 如果没有写@Override,该重写还是会重写
- 如果写了@Override注解,编译器在编译时就会检查该方法是否真的重写了父类方法,如果没有重写就会报错。
- 在@Override的定义中,@interface表示一个注解类,和interface表示接口不一样;@Target(ElementType.METHOD)表示该注解只能修饰方法;@Target是修饰注解的注解,是元注解。
-
@Deprecated简介
- @Deprecated注解表示某个程序的元素,比如方法、类已经过时了
- 但是该过时的元素还是可以用的,只是不推荐使用
- 通过查看@Deprecated的定义,可以知道该注解可用于构造器、成员变量、局部变量、方法、包、参数、类型。
- @Deprecated可以用于新老元素的过渡,比如将jdk8升级到jdk11时,可以将旧的类注解,推荐使用新的类。
-
@SupressWarnings简介
-
当我们不希望看到编译器警告的时候,可以使用@SupressWarnings注解来抑制警告信息
-
语法:@SupressWarnings({“”}),在大括号中可以写入希望抑制的警告信息类型的数组
-
@SuppressWarnings 常用参数列表(JDK 8)
参数名 用途 all抑制所有类型的警告(最宽泛的用法)。 unchecked抑制 “未检查的类型转换” 警告(如泛型擦除导致的警告)。 deprecation抑制 “使用已过时的类或方法” 警告。 rawtypes抑制 “使用原始类型(raw type)” 警告(如 List而非List<String>)。unused抑制 “未使用的变量 / 方法 / 类” 警告。 null抑制 “可能的空指针引用” 警告。 serial抑制 “实现 Serializable 接口但未定义 serialVersionUID” 警告。 finally抑制 “finally 块无法正常完成” 警告(如 finally中存在return)。fallthrough抑制 “switch 语句缺少 break” 警告(允许 case 穿透)。 path抑制 “类路径或源路径中的不存在的路径” 警告。 boxing抑制 “装箱 / 拆箱操作” 警告(如 int与Integer之间的自动转换)。cast抑制 “不必要的类型转换” 警告(如 (String) obj但 obj 已确定为 String)。synthetic-access抑制 “内部类的实体访问” 警告(如内部类访问外部类的 private 成员)。 nls抑制 “非国际化字符串文字” 警告(如直接使用硬编码的字符串)。 restriction抑制 “使用不建议或禁止的引用” 警告(如使用已被 @Deprecated 标记的 API)。 -
@SuppressWarnings写在哪个元素上,那么它的作用范围就是这个元素,比如写在类上就作用于整个类,写在方法上就作用于整个方法,写在语句上就只作用于这个语句。
-
@SupressWarning的源码
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings {String[] value(); }
-
-元注解
-
元注解基本介绍
JDK的元用于修饰其他注解
元注解:在平时开发业务需求时很少用到,但是在开发框架时非常重要
-
元注解的种类(使用不多,了解,不用深入研究)
- Retention //指定注解的作用范围,三种:SOURCE、CLASS、RUNTIME
- Target //指定注解可以在哪些地方使用
- Documented//指定该注解是否会在javadoc中体现
- Inherited//子类会继承父类注解
-
@Retention注解
-
说明
只能用于修饰一个Annotation定义,用于指定该Annotation可以保留多长时间。@Retention包含一个RetentionPolicy类型的成员变量,使用@Retention时必须为该value成员变量指定值
-
@Retention的三种值
- RetentionPolicy.SOURCE:编译器使用后,直接丢弃这种策略的注释
- RetentionPolicy.CLASS:编译器将把注释记录在class文件中。当运行Java程序时,JVM不会保留注解,这是默认值。
- RetentionPolicy.RUNTIME:编译器将把注释记录在class文件中,当运行Java程序时,JVM会保留注释,程序可以通过反射获取该注释
-
-
@Target注解
-
说明
用于修饰Annotation定义,用于指定被修饰的Annotation能用于修饰哪些程序元素。@Target也包含一个名为value的成员变量
-
-
@Documented注解
-
说明
用于指定被该元Annotation修饰的Annotation类将被javadoc工具提取为文档,即在生成文档时,可以看到该注解。定义为Documented的注解必须设置Retention值为RUNTIME。
-
-
@Inherited注解
被它修饰的Annotation将具有继承性,如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注释
