第九章:Java_枚举类和注解

淡淡的烟草味﹌ 2022-07-12 05:54 307阅读 0赞

一、枚举类

1.如何自定义枚举类。 枚举类:类的对象是有限个的,确定的。

  • 1.1 私有化类的构造器,保证不能在类的外部创建其对象
  • 1.2 在类的内部创建枚举类的实例。声明为:public static final
  • 1.3 若类有属性,那么属性声明为:private final 。此属性在构造器中赋值。

2.使用enum关键字定义枚举类

  • 2.1其中常用的方法:values() valueOf(String name);
  • 2.2枚举类如何实现接口 :①让类实现此接口,类的对象共享同一套接口的抽象方法的实现。②让类的每一个对象都去实现接口的抽象方法,进而通过类的对象调用被重写的抽象方法时,执行的效果不同

    public class TestSeason1 {

    1. public static void main(String[] args) {
    2. Season1 spring = Season1.SPRING;
    3. System.out.println(spring);
    4. spring.show();
    5. System.out.println(spring.getSeasonName());
    6. System.out.println();
    7. //1.values()
    8. Season1[] seasons = Season1.values();
    9. for(int i = 0;i < seasons.length;i++){
    10. System.out.println(seasons[i]);
    11. }
    12. //2.valueOf(String name):要求传入的形参name是枚举类对象的名字。
    13. //否则,报java.lang.IllegalArgumentException异常
    14. String str = "WINTER";
    15. Season1 sea = Season1.valueOf(str);
    16. System.out.println(sea);
    17. System.out.println();
    18. Thread.State[] states = Thread.State.values();
    19. for(int i = 0;i < states.length;i++){
    20. System.out.println(states[i]);
    21. }
    22. sea.show();
    23. }

    }
    interface Info{

    1. void show();

    }
    //枚举类
    enum Season1 implements Info{

    1. SPRING("spring", "春暖花开"){
    2. public void show(){
    3. System.out.println("春天在哪里?");
    4. }
    5. },
    6. SUMMER("summer", "夏日炎炎"){
    7. public void show(){
    8. System.out.println("生如夏花");
    9. }
    10. },
    11. AUTUMN("autumn", "秋高气爽"){
    12. public void show(){
    13. System.out.println("秋天是用来分手的季节");
    14. }
    15. },
    16. WINTER("winter", "白雪皑皑"){
    17. public void show(){
    18. System.out.println("冬天里的一把火");
    19. }
    20. };
    21. private final String seasonName;
    22. private final String seasonDesc;
    23. private Season1(String seasonName,String seasonDesc){
    24. this.seasonName = seasonName;
    25. this.seasonDesc = seasonDesc;
    26. }
    27. public String getSeasonName() {
    28. return seasonName;
    29. }
    30. public String getSeasonDesc() {
    31. return seasonDesc;
    32. }
    33. @Override
    34. public String toString() {
    35. return "Season [seasonName=" + seasonName + ", seasonDesc="
    36. + seasonDesc + "]";
    37. }

    // public void show(){
    // System.out.println(“这是一个季节”);
    // }
    }

【来源其他博文:】
枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示。

1、常量的使用
在JDK1.5之前,我们定义常量都是:public static fianl….。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。

  1. public enum Color {
  2. RED, GREEN, BLANK, YELLOW
  3. }

使用:

  1. public class B {
  2. public static void main(String[] args) {
  3. System.out.println( isRed( Color.BLANK ) ) ; //结果: false
  4. System.out.println( isRed( Color.RED ) ) ; //结果: true
  5. }
  6. static boolean isRed( Color color ){
  7. if ( Color.RED.equals( color )) {
  8. return true ;
  9. }
  10. return false ;
  11. }
  12. }

或者 switch 的使用:

  1. public class B {
  2. public static void main(String[] args) {
  3. showColor( Color.RED );
  4. }
  5. static void showColor(Color color){
  6. switch ( color ) {
  7. case BLANK:
  8. System.out.println( color );
  9. break;
  10. case RED :
  11. System.out.println( color );
  12. break;
  13. default:
  14. System.out.println( color );
  15. break;
  16. }
  17. }
  18. }

2、自定义函数

  1. public enum Color {
  2. RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
  3. private String name ;
  4. private int index ;
  5. private Color( String name , int index ){
  6. this.name = name ;
  7. this.index = index ;
  8. }
  9. public String getName() {
  10. return name;
  11. }
  12. public void setName(String name) {
  13. this.name = name;
  14. }
  15. public int getIndex() {
  16. return index;
  17. }
  18. public void setIndex(int index) {
  19. this.index = index;
  20. }
  21. }

使用:

  1. public class B {
  2. public static void main(String[] args) {
  3. //输出某一枚举的值
  4. System.out.println( Color.RED.getName() );
  5. System.out.println( Color.RED.getIndex() );
  6. //遍历所有的枚举
  7. for( Color color : Color.values()){
  8. System.out.println( color + " name: " + color.getName() + " index: " + color.getIndex() );
  9. }
  10. }
  11. }

结果:
红色
1
RED name: 红色 index: 1
GREEN name: 绿色 index: 2
BLANK name: 白色 index: 3
YELLO name: 黄色 index: 4

===================================

我们现在来深入了解下枚举。
先参考几篇文章:

  • ①深入理解Java枚举类型(enum)
  • ②Java 中的枚举 (enum)

在①中这样讲到。如下代码:

  1. public class EnumDemo {
  2. public static void main(String[] args){
  3. //直接引用
  4. Day day =Day.MONDAY;
  5. }
  6. }
  7. //定义枚举类型
  8. enum Day {
  9. MONDAY, TUESDAY, WEDNESDAY,
  10. THURSDAY, FRIDAY, SATURDAY, SUNDAY
  11. }

反编译可以看到,是这样的:

  1. //反编译Day.class
  2. final class Day extends Enum
  3. {
  4. //编译器为我们添加的静态的values()方法
  5. public static Day[] values()
  6. {
  7. return (Day[])$VALUES.clone();
  8. }
  9. //编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法
  10. public static Day valueOf(String s)
  11. {
  12. return (Day)Enum.valueOf(com/zejian/enumdemo/Day, s);
  13. }
  14. //私有构造函数
  15. private Day(String s, int i)
  16. {
  17. super(s, i);
  18. }
  19. //前面定义的7种枚举实例
  20. public static final Day MONDAY;
  21. public static final Day TUESDAY;
  22. public static final Day WEDNESDAY;
  23. public static final Day THURSDAY;
  24. public static final Day FRIDAY;
  25. public static final Day SATURDAY;
  26. public static final Day SUNDAY;
  27. private static final Day $VALUES[];
  28. static
  29. {
  30. //实例化枚举实例
  31. MONDAY = new Day("MONDAY", 0);
  32. TUESDAY = new Day("TUESDAY", 1);
  33. WEDNESDAY = new Day("WEDNESDAY", 2);
  34. THURSDAY = new Day("THURSDAY", 3);
  35. FRIDAY = new Day("FRIDAY", 4);
  36. SATURDAY = new Day("SATURDAY", 5);
  37. SUNDAY = new Day("SUNDAY", 6);
  38. $VALUES = (new Day[] {
  39. MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
  40. });
  41. }
  42. }

从反编译的代码可以看出编译器确实帮助我们生成了一个Day类(注意该类是final类型的,将无法被继承)而且该类继承自java.lang.Enum类,该类是一个抽象类(稍后我们会分析该类中的主要方法),除此之外,编译器还帮助我们生成了7个Day类型的实例对象分别对应枚举中定义的7个日期,这也充分说明了我们前面使用关键字enum定义的Day类型中的每种日期枚举常量也是实实在在的Day实例对象,只不过代表的内容不一样而已。

现在能明白:使用关键字enum定义的枚举类型,在编译期后,将转换成为一个实实在在的类,而在该类中,会存在每个在枚举类型中定义好变量的对应实例对象,如上述的MONDAY枚举类型对应public static final Day MONDAY;,同时编译器会为该类创建两个方法,分别是values()和valueOf()。

所以最前面的关于季节的代码:

  1. public class Season1Demo{
  2. public static void main(String[] args) {
  3. Season spring = Season.WINTER;
  4. spring.show();
  5. Season.SPRING.show();
  6. Season.AUTUMN.show();
  7. }
  8. }
  9. interface Info {
  10. void show();
  11. }
  12. // 枚举类
  13. enum Season implements Info {
  14. SPRING("spring", "春暖花开") {
  15. // public void show() {
  16. // System.out.println("春天在哪里?");
  17. // }
  18. },
  19. SUMMER("summer", "夏日炎炎") {
  20. //该实例重写了 show 方法
  21. public void show() {
  22. System.out.println("生如夏花");
  23. }
  24. },
  25. AUTUMN("autumn", "秋高气爽") {
  26. public void show() {
  27. System.out.println("秋天是用来分手的季节");
  28. }
  29. },
  30. WINTER("winter", "白雪皑皑") {
  31. public void show() {
  32. System.out.println("冬天里的一把火");
  33. }
  34. };
  35. private final String seasonName;
  36. private final String seasonDesc;
  37. private Season(String seasonName, String seasonDesc) {
  38. this.seasonName = seasonName;
  39. this.seasonDesc = seasonDesc;
  40. }
  41. public String getSeasonName() {
  42. return seasonName;
  43. }
  44. public String getSeasonDesc() {
  45. return seasonDesc;
  46. }
  47. @Override
  48. public String toString() {
  49. return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]";
  50. }
  51. public void show(){
  52. System.out.println("这是一个季节");
  53. }
  54. }

结果:

  1. 冬天里的一把火
  2. 这是一个季节
  3. 秋天是用来分手的季节

我个人小结:枚举Season最后转换成了Season类(继承了Enum类),然后在该类中定义好了类型为Season的成员变量SPRINGSUMMERAUTUMNWINTER并实例化。
在引用另外看到的篇文章写道的:

enum这个关键字,可以理解为跟class差不多,这也个单独的类。可以看到,上面的例子里面有属性,有构造方法,有getter,也可以有setter,但是一般都是构造传参数。还有其他自定义方法。那么在这些东西前面的,以逗号隔开的,最后以分号结尾的,这部分叫做,这个枚举的实例。也可以理解为,class new 出来的实例对象。这下就好理解了。只是,class,new对象,可以自己随便new,想几个就几个,而这个enum关键字,他就不行,他的实例对象,只能在这个enum里面体现。也就是说,他对应的实例是有限的。这也就是枚举的好处了,限制了某些东西的范围,举个栗子:一年四季,只能有春夏秋冬,你要是字符串表示的话,那就海了去了,但是,要用枚举类型的话,你在enum的大括号里面把所有的选项,全列出来,那么这个季节的属性,对应的值,只能在里面挑。不能有其他的。

所以:

  1. SPRING("spring", "春暖花开") {
  2. public void show() {
  3. System.out.println("春天在哪里?");
  4. }
  5. },

该代码相当就是new出了Season对象并实例化,该如果这里没写show()方法则调用的Season实现的show()方法,但这里重新定义了,相当于覆盖了show()方法。

再看一个例子(包含抽象方法的枚举类):

定义一个 Operation 枚举类,有4个枚举值PLUS、MINUS、TIMES、DIVIDE,分别代表加、减、乘、除,该枚举类有一个 calculate() 方法,用于完成计算。

  1. public enum Operation {
  2. // 用于执行加法运算
  3. PLUS { // 花括号部分其实是一个匿名内部子类
  4. @Override
  5. public double calculate(double x, double y) {
  6. return x + y;
  7. }
  8. },
  9. // 用于执行减法运算
  10. MINUS { // 花括号部分其实是一个匿名内部子类
  11. @Override
  12. public double calculate(double x, double y) {
  13. // TODO Auto-generated method stub
  14. return x - y;
  15. }
  16. },
  17. // 用于执行乘法运算
  18. TIMES { // 花括号部分其实是一个匿名内部子类
  19. @Override
  20. public double calculate(double x, double y) {
  21. return x * y;
  22. }
  23. },
  24. // 用于执行除法运算
  25. DIVIDE { // 花括号部分其实是一个匿名内部子类
  26. @Override
  27. public double calculate(double x, double y) {
  28. return x / y;
  29. }
  30. };
  31. //为该枚举类定义一个抽象方法,枚举类中所有的枚举值都必须实现这个方法
  32. public abstract double calculate(double x, double y);
  33. }

从上可以看出,掌握、理解枚举,重要要知道枚举、和枚举变量的实质是什么
枚举最后转换就是一个特殊的类,其中的枚举变量就是实例化对象。可以就这么看:

  1. public class HelloDemo2 {
  2. public static void main(String[] args) {
  3. Season1 SPRING = new Season1("spring", "春暖花开") {
  4. public void show() {
  5. System.out.println("春天在哪里?");
  6. };
  7. };
  8. SPRING.show();
  9. }
  10. }
  11. interface Info1{
  12. void show();
  13. }
  14. class Season1 implements Info1{
  15. private String seasonName;
  16. private String seasonDesc;
  17. public Season1(String seasonName, String seasonDesc) {
  18. this.seasonName = seasonName;
  19. this.seasonDesc = seasonDesc;
  20. }
  21. @Override
  22. public void show() {
  23. System.out.println("这是一个季节");
  24. }
  25. }

二、注解Annotation

1.JDK提供的常用的三个注解

@Override: 限定重写父类方法, 该注释只能用于方法
@Deprecated: 用于表示某个程序元素(类, 方法等)已过时
@SuppressWarnings: 抑制编译器警告

2.如何自定义注解
以SuppressWarnings为例进行创建即可

3.元注解:可以对已有的注解进行解释说明。
这里写图片描述

Retention: SOURCE CLASS RUNTIME
Target:
Documented:javadoc
Inherited

这里写图片描述

发表评论

表情:
评论列表 (有 0 条评论,307人围观)

还没有评论,来说两句吧...

相关阅读

    相关 注解

    推荐使用枚举定义常量 1、枚举常量更简单 2、枚举常量属于稳态型 3、枚举具有内置方法 4、枚举可以自定义方法 枚举类型是不能有继承的,也就是说一个枚举常量定义