你不会工作1年了连枚举都还不知道吧?

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 你不会工作1年了连枚举都还不知道吧?,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

💗推荐阅读文章💗

🎉本博客知识点收录于🎉👉🚀《JavaSE系列教程》🚀—>✈️18【枚举、类加载器、动态代理】✈️

一、枚举(Enum)

1.1 枚举概述

枚举(enum),全称enumeration是JDK 1.5 中引入的新特性。Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。

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

1.2 定义枚举类型

1.2.1 静态常量案例

我们使用静态常量来设置一个季节类:

package com.dfbz.demo01_静态成员变量;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Season {
    public static final Integer SPRING = 1;
    public static final Integer SUMMER = 2;
    public static final Integer AUTUMN = 3;
    public static final Integer WINTER = 4;
}

1/2/3/4分别代表不同的含义

测试类:

package com.dfbz.demo01_静态成员变量;

import org.junit.Test;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo01_静态成员变量 {

    @Test
    public void test1() {
        method(Season.SPRING);
        method(Season.WINTER);
    }
    public void method(Integer season) {

        switch (season) {
            case 1:
                System.out.println("Spring!");          // 具体的逻辑
                break;
            case 2:
                System.out.println("Summer!");           // 具体的逻辑
                break;
            case 3:
                System.out.println("Autumn!");          // 具体的逻辑
                break;
            case 4:
                System.out.println("Winter!");           // 具体的逻辑
                break;
        }
    }
}

1.2.2 枚举案例

Java 枚举类使用enum关键字来定义,各个常量使用逗号来分割。

package com.dfbz.demo02;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public enum Season {
    SPRING,SUMMER,AUTUMN,WINTER
}

Tips:定义枚举类的关键字是enum,而不是Enum,在Java中所有关键字都是小写的!

其中SPRINGSUMMERAUTUMNWINTER都是枚举项它们都是本类的实例,本类一共就只有四个实例对象。并且只能通过这四个关键字获取Season类的实例对象,不能使用new来创建枚举类的对象

package com.dfbz.demo02_枚举的使用;

import org.junit.Test;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo01_枚举的使用 {

    @Test
    public void test1() {

        // 通过枚举项来获取枚举实例
        Season spring = Season.SPRING;
        Season spring2 = Season.SPRING;

        // 通过相同的枚举项获取的枚举实例是一样的
        System.out.println(spring == spring2);          // true

        // 不同的枚举项获取的枚举实例是不一样的
        Season autumn = Season.AUTUMN;
        System.out.println(spring == autumn);           // false
    }
}

1.2.3 枚举与switch

使用枚举,能让我们的代码可读性更强。

package com.dfbz.demo02_枚举的使用;

import org.junit.Test;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo02_枚举与switch {

    @Test
    public void test1() {
        Season season = Season.AUTUMN;

        switch (season){
            case SPRING:
                System.out.println("春天~");
                break;
            case SUMMER:
                System.out.println("夏天!");
                break;
            case AUTUMN:
                System.out.println("秋天@");
                break;
            case WINTER:
                System.out.println("冬天&");
                break;
            default:
                System.out.println("错误的季节");
        }
    }
}

1.3 枚举的用法

1.3.1 枚举类的成员

枚举类和正常的类一样,可以有实例变量,实例方法,静态方法等等

  • 定义枚举类:
package com.dfbz.demo02_枚举的使用;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public enum Color {

    // 在枚举常量后面还有其他成员时,分号是必须的。枚举常量必须在枚举类中所有成员的上方声明
    RED, GREEN, BLUE;

    public String aaa = "AAA";              // 普通成员变量

    public static String bbb = "BBB";       // 静态成员变量

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static void method() {
        System.out.println("enum hello~");
    }
}

Tips:当枚举项后面有其他成员(构造方法、成员变量、成员方法)时,最后一个枚举项必须加分号;

  • 测试类:
package com.dfbz.demo02_枚举的使用;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo03_枚举类的成员 {
    public static void main(String[] args) {
        // 访问静态成员变量
        System.out.println(Color.bbb);

        // 访问静态成员方法
        Color.method();

        // 通过枚举项获取实例
        Color red = Color.RED;

        // 通过枚举实例调用成员方法
        red.setName("红色");

        // 通过枚举实例调用成员方法
        System.out.println(red.getName());			// 红色

    }
}

1.3.2 枚举类的构造方法

1)枚举的无参构造方法

枚举类也可以有构造方法,构造方法默认都是private修饰,而且只能是private。因为枚举类的实例不能让外界来创建!

默认情况下,所有的枚举项的创建都是调用枚举类的无参构造方法,并且在获取任何一个枚举实例时,其他实例都将会被创建

package com.dfbz.demo03;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public enum Direction {

    // 在枚举常量后面还有其他成员时,分号是必须的。枚举常量必须在枚举类中所有成员的上方声明
    FRONT,BEHIND,LEFT,RIGHT;

    // 枚举类的构造方法都是private修饰的,可写可不写
    Direction(){
        System.out.println("Direction创建了...");
    }
}

Tips:

  • 1:当枚举项后面有其他成员(构造方法、成员变量、成员方法)时,最后一个枚举项必须加分号;
  • 2:所有的枚举类的构造方法都是私有的(private关键字可加可不加)

测试类:

package com.dfbz.demo02_枚举的使用;

import org.junit.Test;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo04_枚举类的构造方法 {


    /**
     * 枚举的无参构造方法
     */
    @Test
    public void test1() {

        // 运行代码将会创建四个枚举实例
        Direction behind = Direction.BEHIND;
    }

}

运行结果:

在这里插入图片描述

Tips:一旦创建了枚举实例,便会初始化里面的所有枚举项;创建枚举项就等同于调用本类的无参构造器,所以FRONT、BEHIND、LEFT、RIGHT四个枚举项等同于调用了四次无参构造器

2)枚举的有参构造方法

枚举项就是枚举类的实例,在创建定义枚举项时其实就是创建枚举类的实例,因此在定义枚举项就要传递实际的参数

  • 定义枚举项:
package com.dfbz.demo02_枚举的使用;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public enum  Week {
    // 枚举项就是枚举类的实例,在创建定义枚举项时其实就是创建枚举的实例,因此在定义枚举项就要传递实际的参数
    MONDAY("星期一",1),
    TUESDAY("星期二"),
    WEDNESDAY,
    THURSDAY("星期四",3),
    FRIDAY("星期五",4),
    SATURDAY("星期六",5),
    SUNDAY("星期六",4);

    private String name;
    private Integer loveLevel;

    // 注意: 枚举类的构造方法只能是私有(默认情况下也是私有)
    Week() {                                    // 空参构造
    }

    Week(String name) {                         // 有参构造
        this.name = name;
    }

    Week(String name, Integer loveLevel) {      // 有参构造
        this.name = name;
        this.loveLevel=loveLevel;
    }

    public void show() {
        System.out.println("我是【" + name + "】,我的喜好程度是【" + loveLevel + "】颗星");
    }

    @Override
    public String toString() {
        return "Week{" +
                "name='" + name + '\'' +
                ", loveLevel=" + loveLevel +
                '}';
    }
}
  • 测试类:
/**
 * 枚举的有参构造方法
 */
@Test
public void test2() {
    // 获取第一个枚举实例时,将会创建所有的枚举实例
    Week friday = Week.FRIDAY;
    friday.show();
    System.out.println(friday);
    System.out.println("---------------");

    Week saturday = Week.SATURDAY;
    saturday.show();
    System.out.println(saturday);
    System.out.println("---------------");

    Week tuesday = Week.TUESDAY;
    tuesday.show();
    System.out.println(tuesday);
    System.out.println("---------------");

    Week wednesday = Week.WEDNESDAY;
    wednesday.show();
    System.out.println(wednesday);
    System.out.println("---------------");
}
  • 运行效果如下:

在这里插入图片描述

1.3.3 枚举中的抽象方法

枚举类中可以包含抽象方法,但是在定义枚举项时必须重写该枚举类中的所有抽象方法;

我们前面说过,每一个枚举项其实都是枚举类的实例对象,因此如果当前枚举类包含抽象方法时,在定义枚举项时就需要重写此枚举类的所有抽象方法,这跟我们以前使用的匿名内部类很相似;

  • 首先定义一个抽象类(包含了抽象方法):
package com.dfbz.demo03_枚举的抽象方法;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public abstract class AbstractSeason {

    public abstract void fun();
}
  • 实例化这个抽象类的时候,我们必须抽象其所有的抽象方法:
package com.dfbz.demo03_枚举的抽象方法;

import org.junit.Test;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo01_枚举的抽象方法 {
    @Test
    public void test1() {
        // 可以把abstractSeason看做是一个枚举项,在定义枚举项时必须重写枚举类的所有抽象方法
        AbstractSeason abstractSeason = new AbstractSeason() {
            @Override
            public void fun() {
                System.out.println("重写了这个抽象类的所有抽象方法");
            }
        };
    }
}

当枚举类中含有抽象方法的时候,定义枚举项时,必须重写该枚举类中所有的抽象方法,像下面这种就是一种错误的定义:

package com.dfbz.demo03_枚举的抽象方法;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public enum Season {

    SPRING;         // 编译报错,定义枚举项时必须重写枚举类包含的所有抽象方法

    public abstract void fun();
}
  • 正确写法:
package com.dfbz.demo03_枚举的抽象方法;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public enum Season {

    SPRING(){
        @Override
        public void fun() {
            System.out.println("我是春天~");
        }
    };        

    public abstract void fun();
}
  • 定义多几个枚举项:
package com.dfbz.demo03_枚举的抽象方法;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public enum Season {

    SPRING(){
        @Override
        public void fun() {
            System.out.println("我是春天...");
        }
    },          

    SUMMER(){
        @Override
        public void fun() {
            System.out.println("我是夏天~");
        }
    };          

    public abstract void fun();
}
  • 测试类:
@Test
public void test2() {
    Season spring = Season.SPRING;
    Season summer = Season.SUMMER;

    spring.fun();
    summer.fun();
}

在这里插入图片描述

1.4 Enum 类

1.4.1 Enum类中的方法

Java中,所有的枚举类都默认继承与java.lang.Enum类,这说明Enum中的方法所有枚举类都拥有。另外Enum也继承与Object,因此所有的枚举类都拥有与Object类一样的方法;


Enum类中的方法如下:

在这里插入图片描述

Tips:枚举类除了不能拥有Object中的clone、finalize方法外,其他方法都能拥有;

Enum类新增(或重写Object)的方法:

  • int compareTo(E e):比较两个枚举常量谁大谁小,其实比较的就是枚举常量在枚举类中声明的顺序(ordinal值)
  • boolean equals(Object o):比较两个枚举常量是否相等;
  • Class<E> getDeclaringClass():返回此枚举类的Class对象,这与Object中的getClass()类似;
  • int hashCode():返回枚举常量的hashCode
  • String name():返回枚举常量的名字;
  • int ordinal():返回枚举常量在枚举类中声明的序号,第一个枚举常量序号为0;
  • String toString():把枚举常量转换成字符串;
  • static T valueOf(Class enumType, String name):把字符串转换成枚举常量。

1.4.2 测试方法功能

  • 定义一个枚举类:
package com.dfbz.demo07;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public enum  Season {
    SPRING,SUMMER,AUTUMN,WINTER;
}
  • 测试类:
package com.dfbz.demo04_Enum;

import org.junit.Test;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo01_Enum类的方法使用 {

    Season spring = Season.SPRING;              // ordinal:0
    Season summer = Season.SUMMER;              // ordinal:1
    Season autumn = Season.AUTUMN;              // ordinal:2
    Season winter = Season.WINTER;              // ordinal:3

    @Test
    public void test1() {
        System.out.println(spring.compareTo(spring));           // 0-0=0
        System.out.println(spring.compareTo(summer));           // 0-1=-1
        System.out.println(winter.compareTo(summer));           // 3-1=2
        System.out.println(winter.compareTo(spring));           // 3-0=3
    }

    @Test
    public void test2() {

        Season spring2 = Season.SPRING;

        System.out.println(spring == spring2);                  // true
        System.out.println(spring.equals(spring2));             // 枚举对象的equals方法比较的是内存地址值(返回true)
    }

    @Test
    public void test3() {
        Class<Season> clazz = spring.getDeclaringClass();
        Class<? extends Season> clazz2 = spring.getClass();

        System.out.println(clazz == clazz2);            // true
    }

    @Test
    public void test4() {

        int hashCode = spring.hashCode();
        System.out.println(hashCode);           // 2027961269

        String name = spring.name();
        System.out.println(name);               // SPRING

        int ordinal_spring = spring.ordinal();
        int ordinal_summer = summer.ordinal();
        int ordinal_autumn = autumn.ordinal();
        int ordinal_winter = winter.ordinal();

        System.out.println(ordinal_spring);         // 0
        System.out.println(ordinal_summer);         // 1
        System.out.println(ordinal_autumn);         // 2
        System.out.println(ordinal_winter);         // 3
    }

    @Test
    public void test5() {

        Season s = Season.valueOf("SPRING");        // 通过枚举项的名称获取枚举项

        System.out.println(s == spring);            // true(返回的还是同一个枚举项)
    }
}

1.4.3 枚举的两个抽象方法

每个枚举类都有两个静态方法,而且这两个方法不是父类中的方法。这又是枚举类特殊的地方;

  • static T[] values():返回本类所有枚举项;

  • static T valueOf(String name):通过枚举项的名字返回枚举项;


  • 测试类:
@Test
public void test6() {

    // 获取这个枚举类中所有的枚举项
    Season[] values = Season.values();
    for (Season value : values) {
        System.out.println(value);
    }

    // 通过枚举项的名称获取枚举项
    Season s = Season.valueOf("SPRING");
    System.out.println(s == spring);            // true
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/131631.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!