惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Hacker News
The Hacker News
F
Full Disclosure
Cloudbric
Cloudbric
Blog — PlanetScale
Blog — PlanetScale
W
WeLiveSecurity
N
News and Events Feed by Topic
T
Troy Hunt's Blog
V2EX - 技术
V2EX - 技术
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
B
Blog
GbyAI
GbyAI
C
Check Point Blog
B
Blog RSS Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Recorded Future
Recorded Future
The Last Watchdog
The Last Watchdog
N
News and Events Feed by Topic
T
The Blog of Author Tim Ferriss
O
OpenAI News
V
V2EX
人人都是产品经理
人人都是产品经理
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
WordPress大学
WordPress大学
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
Security @ Cisco Blogs
C
Cisco Blogs
Security Latest
Security Latest
S
Security Affairs
V
Visual Studio Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 司徒正美
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Azure Blog
Microsoft Azure Blog
Last Week in AI
Last Week in AI
AWS News Blog
AWS News Blog
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
PCI Perspectives
PCI Perspectives
博客园_首页
U
Unit 42
Google DeepMind News
Google DeepMind News
Hugging Face - Blog
Hugging Face - Blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
The Register - Security
The Register - Security
N
Netflix TechBlog - Medium
L
LINUX DO - 热门话题
H
Hacker News: Front Page

博客园 - 远洪

大模型常用术语 windows 使用sshAgent 加载秘钥 再次认识java反射 再次认识java注解 再次认识java泛型 java中类的分类 java类中的成员变量,静态变量与局部变量 使用CCProxy让手机访问电脑能访问的网址 playwright启动后报错net::ERR_CERT_COMMON_NAME_INVALID 解决方法 debian 或ubuntu安装使用tigervnc python 实例属性、类属性、实例方法、类方法、静态方法 python面向对象封装,私有变量 docker compose使用 docker 自定义网络 Dockerfile 使用 golang进程(主线程)与协程 go语言多态中的类型断言 java中的多态与golang中的多态 golang 定义接口
再谈java枚举enum
远洪 · 2024-10-13 · via 博客园 - 远洪

一、认识枚举

枚举是一种特殊类

枚举的定义:

修饰符 enum 枚举名 {
       枚举项1,枚举项2,枚举项3;
       其他成员;
}

注意:

  • 枚举的第一行只能写枚举项,多个枚举项用逗号(,),隔开
  • 每一个枚举项都是一个常量(不可改变值),且都指向一个该枚举的对象

二、为什么要使用枚举

例如,有这么一方法,需要获取男孩和女孩的一些特征。传入男孩,就返回男孩的信息,传入女孩,就返回女孩的信息。

我们来看以下几种方法实现。

方法一

我们用1表示男孩,2表示女孩,代码如下:

package org.example.enumX;

public class Example2 {
    public static void main(String[] args) {
        choseStudent(1);
    }
    public static void choseStudent(int sex){
        switch (sex){
            case 1:
                System.out.println("男孩的特征");
                break;
            case 2:
                System.out.println("女孩的特征");
                break;
            default:
                System.out.println("参数错误");
        }
    }
}
// 程序输出:男孩的特征

以上代码虽然实现了业务逻辑,但是方法传1和传2并不能让人很快理解该值的意思,甚至我们可以传3,4,5,6,7 没有任何限制。

为了让代码更容易理解, 我们吧男孩和女孩封装到一个类里面,如下,方法二

方法二

同样,用1表示男孩,2表示女孩,只是我们把信息封装到一个类里面了。

package org.example.enumX;
class StudentA{
    public static final int boy = 1;
    public static final int girl = 2;
}

public class Example1 {
    public static void main(String[] args) {
        choseStudent(StudentA.boy);
    }
    public static void choseStudent(int sex){
        switch (sex){
            case 1:
                System.out.println("男孩的特征");
                break;
            case 2:
                System.out.println("女孩的特征");
                break;
            default:
                System.out.println("参数错误");
        }
    }
}

以上代码,我们就很清楚参数传入的是一个男孩,代码可读性变好了。但是我们仍然能够传其他的int类型值。

为了限制该方法传值的问题,于是我们引入了枚举,如下方法三:

方法三

使用枚举来实现该功能

package org.example;

enum StudentB{
    BOY,GIRL
}

public class Example3 {
    public static void main(String[] args) {
        choseStudent(StudentB.BOY);
    }
    public static void choseStudent(StudentB sex){
        switch (sex){
            case BOY:
                System.out.println("男孩的特征");
                break;
            case GIRL:
                System.out.println("女孩的特征");
                break;
            default:
                System.out.println("参数错误");
        }
    }
}

这样不仅提高了代码的可读性,也限制了调用者对该方法的传值。

枚举的底层原理

我们将方法二中的类声明为final 防止继承,同事将构造方法声明为private以防止外部实例化。这样我们就可以保证,再程序内Student就只能有我们定义好的常量。如下:

package org.example.enumX;

final class StudentD{
    public static final StudentD BOY = new StudentD();
    public static final StudentD GIRL =  new StudentD();
    private StudentD(){}
}

通过上面的代码,我们也能限制调用者传递的内容。以上代码就类似为枚举的原理。

我们将方法三中的StudentB 枚举类的class文件进行反编译,可以看到如下代码:

PS D:\project\IDEAjava\testPro\demos\target\classes\org\example> javap .\StudentB.class
Compiled from "Example3.java"
final class org.example.StudentB extends java.lang.Enum<org.example.StudentB> {
  public static final org.example.StudentB BOY;
  public static final org.example.StudentB GIRL;
  public static org.example.StudentB[] values();
  public static org.example.StudentB valueOf(java.lang.String);
  static {};
}

 带参数的枚举项

由于每一个枚举项都是该枚举的一个实例,因此我们给枚举定义了构造方法之后,枚举项在实例化的时候就可以带上参数了

package org.example.test;

enum StudentD{
    BOY("男","短头发"),  
    GIRL("女","长头发");

    private final String sex;
    private final String hair;

    private StudentD(String sex,String hair){
        this.sex = sex;
        this.hair = hair;
    }

    public String getInfo(){
        String info = "性别:" + this.sex + "头发:" + this.hair;
        return info;
    }
}
public class Example4 {
    public static void main(String[] args) {
        choseStudent(StudentB.GIRL);
    }
    public static void choseStudent(StudentB stu){
        switch (stu){
            case BOY:
                System.out.println("男孩的特征:" + StudentD.BOY.getInfo());
                break;
            case GIRL:
                System.out.println("女孩的特征:" + StudentD.GIRL.getInfo());
                break;
            default:
                System.out.println("参数错误");
        }
    }
}

运行结果:

女孩的特征:性别:女头发:长头发