恕我直言,我怀疑你并不会用 Java 枚举(1)

简介: 恕我直言,我怀疑你并不会用 Java 枚举

开门见山地说吧,enum(枚举)是 Java 1.5 时引入的关键字,它表示一种特殊类型的类,默认继承自 java.lang.Enum。


为了证明这一点,我们来新建一个枚举 PlayerType:


public enum PlayerType {
    TENNIS,
    FOOTBALL,
    BASKETBALL
}

两个关键字带一个类名,还有大括号,以及三个大写的单词,但没看到继承 Enum 类啊?别着急,心急吃不了热豆腐啊。使用 JAD 查看一下反编译后的字节码,就一清二楚了。


public final class PlayerType extends Enum
{
    public static PlayerType[] values()
    {
        return (PlayerType[])$VALUES.clone();
    }
    public static PlayerType valueOf(String name)
    {
        return (PlayerType)Enum.valueOf(com/cmower/baeldung/enum1/PlayerType, name);
    }
    private PlayerType(String s, int i)
    {
        super(s, i);
    }
    public static final PlayerType TENNIS;
    public static final PlayerType FOOTBALL;
    public static final PlayerType BASKETBALL;
    private static final PlayerType $VALUES[];
    static 
    {
        TENNIS = new PlayerType("TENNIS", 0);
        FOOTBALL = new PlayerType("FOOTBALL", 1);
        BASKETBALL = new PlayerType("BASKETBALL", 2);
        $VALUES = (new PlayerType[] {
            TENNIS, FOOTBALL, BASKETBALL
        });
    }
}


看到没?PlayerType 类是 final 的,并且继承自 Enum 类。这些工作我们程序员没做,编译器帮我们悄悄地做了。此外,它还附带几个有用静态方法,比如说 values() 和 valueOf(String name)。


01、内部枚举


好的,小伙伴们应该已经清楚枚举长什么样子了吧?既然枚举是一种特殊的类,那它其实是可以定义在一个类的内部的,这样它的作用域就可以限定于这个外部类中使用。


public class Player {
    private PlayerType type;
    public enum PlayerType {
        TENNIS,
        FOOTBALL,
        BASKETBALL
    }
    public boolean isBasketballPlayer() {
      return getType() == PlayerType.BASKETBALL;
    }
    public PlayerType getType() {
        return type;
    }
    public void setType(PlayerType type) {
        this.type = type;
    }
}



PlayerType 就相当于 Player 的内部类,isBasketballPlayer() 方法用来判断运动员是否是一个篮球运动员。


由于枚举是 final 的,可以确保在 Java 虚拟机中仅有一个常量对象(可以参照反编译后的静态代码块「static 关键字带大括号的那部分代码」),所以我们可以很安全地使用“==”运算符来比较两个枚举是否相等,参照 isBasketballPlayer() 方法。


那为什么不使用 equals() 方法判断呢?


if(player.getType().equals(Player.PlayerType.BASKETBALL)){};

if(player.getType() == Player.PlayerType.BASKETBALL){};

1

2

“==”运算符比较的时候,如果两个对象都为 null,并不会发生 NullPointerException,而 equals() 方法则会。


另外, “==”运算符会在编译时进行检查,如果两侧的类型不匹配,会提示错误,而 equals() 方法则不会。


image.png


02、枚举可用于 switch 语句


这个我在之前的一篇我去的文章中详细地说明过了,感兴趣的小伙伴可以点击链接跳转过去看一下。


switch (playerType) {
        case TENNIS:
            return "网球运动员费德勒";
        case FOOTBALL:
            return "足球运动员C罗";
        case BASKETBALL:
            return "篮球运动员詹姆斯";
        case UNKNOWN:
            throw new IllegalArgumentException("未知");
        default:
            throw new IllegalArgumentException(
                    "运动员类型: " + playerType);
    }


03、枚举可以有构造方法


如果枚举中需要包含更多信息的话,可以为其添加一些字段,比如下面示例中的 name,此时需要为枚举添加一个带参的构造方法,这样就可以在定义枚举时添加对应的名称了。


public enum PlayerType {
    TENNIS("网球"),
    FOOTBALL("足球"),
    BASKETBALL("篮球");
    private String name;
    PlayerType(String name) {
        this.name = name;
    }
}


04、EnumSet


EnumSet 是一个专门针对枚举类型的 Set 接口的实现类,它是处理枚举类型数据的一把利器,非常高效(内部实现是位向量,我也搞不懂)。


因为 EnumSet 是一个抽象类,所以创建 EnumSet 时不能使用 new 关键字。不过,EnumSet 提供了很多有用的静态工厂方法:


image.png


下面的示例中使用 noneOf() 创建了一个空的 PlayerType 的 EnumSet;使用 allOf() 创建了一个包含所有 PlayerType 的 EnumSet。


public class EnumSetTest {
    public enum PlayerType {
        TENNIS,
        FOOTBALL,
        BASKETBALL
    }
    public static void main(String[] args) {
        EnumSet<PlayerType> enumSetNone = EnumSet.noneOf(PlayerType.class);
        System.out.println(enumSetNone);
        EnumSet<PlayerType> enumSetAll = EnumSet.allOf(PlayerType.class);
        System.out.println(enumSetAll);
    }
}



程序输出结果如下所示:


[]

[TENNIS, FOOTBALL, BASKETBALL]


有了 EnumSet 后,就可以使用 Set 的一些方法了:



相关文章
|
1月前
|
安全 Java
Java 枚举(Enums)解析:提高代码可读性与易维护性
在 Java 中,实现抽象的另一种方式是使用接口。 接口定义 接口是一个完全抽象的类,用于将具有空方法体的相关方法分组:
69 1
|
2月前
|
存储 安全 Java
解密 Java 枚举的奥秘:超越常量的选择
解密 Java 枚举的奥秘:超越常量的选择
31 0
|
3月前
|
开发框架 Java 编译器
Java反射,枚举讲解
Java反射,枚举讲解
43 0
|
7天前
|
Java API
Java基础—笔记—内部类、枚举、泛型篇
本文介绍了Java编程中的内部类、枚举和泛型概念。匿名内部类用于简化类的创建,常作为方法参数,其原理是生成一个隐含的子类。枚举用于表示有限的固定数量的值,常用于系统配置或switch语句中。泛型则用来在编译时增强类型安全性,接收特定数据类型,包括泛型类、泛型接口和泛型方法。
9 0
|
1月前
|
Java
JAVA枚举
JAVA枚举
9 1
|
2月前
|
Java
Java枚举简述
Java枚举简述
15 0
|
3月前
|
网络协议 Java 程序员
完美!腾讯技术官发布Java零基础就业宝典,不用再怀疑人生了
近几年来,互联网行业变化非常大,除了龙头企业的更替,“裁员潮”“失业潮”也不断掀起,尤其是对于年纪太大的程序员真的是不太友好。但是,根据数据统计表明,自2018来,学习IT行业的人不减反增,更有不少其他行业的人转学转行。
|
4月前
|
存储 安全 Java
【Java 枚举】详细介绍枚举的作用以及适用范围
【Java 枚举】详细介绍枚举的作用以及适用范围
|
4月前
|
安全 Java 编译器
Java枚举(enum)
Java枚举(enum)
30 0
|
4月前
|
IDE Java 开发工具
你知道 Java 中关键字 enum 是一个语法糖吗?反编译枚举类
你知道 Java 中关键字 enum 是一个语法糖吗?反编译枚举类
44 0