【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,则其子类将自动具有该注释