《Java编程思想》读书笔记

前言:三年之前就买了《Java编程思想》这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第十七章到第十八章的内容,这一次记录的是第十九章到第二十章的内容

第十九章:枚举类型

关键字enum可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能。

enum的基本特性

我们已经知道,调用enum的values()方法,可以遍历enum实例。values()方法返回enum实例的数组,而且该数组中的元素严格保持其在enum中声明时的顺序,因此你可以在循环中使用values()返回的数组。

创建enum时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum。下面的例子演示了Enum提供的一些功能∶

package enumerated;

/**
 * @author Mr.Sun
 * @date 2022年09月02日 15:58
 *
 * 枚举的基本特性
 */
public class EnumClass {
    public static void main(String[] args) {
        for(Shrubbery s : Shrubbery.values()) {
            System.out.println(s + " ordinal: " + s.ordinal());
            System.out.print(s.compareTo(Shrubbery.CRAWLING) + " ");
            System.out.print(s.equals(Shrubbery.CRAWLING) + " ");
            System.out.println(s == Shrubbery.CRAWLING);
            System.out.println(s.getDeclaringClass());
            System.out.println(s.name());
            System.out.println("----------------------");
        }

        // 从字符串名称生成枚举值
        for(String s : "HANGING CRAWLING GROUND".split(" ")) {
            Shrubbery shrub = Enum.valueOf(Shrubbery.class, s);
            System.out.println(shrub);
        }
    }
}

enum Shrubbery {
    GROUND, CRAWLING, HANGING
}

运行结果如下图:

ordinal()方法返回一个int值,这是每个enum实例在声明时的次序,从0开始。可以使用==来比较enum实例,编译器会自动为你提供equals()和hashCode()方法。Enum类实现了Comparable 接口,所以它具有compareTo()方法。同时,它还实现了Serializable接口。

如果在enum实例上调用getDeclaringClass()方法,我们就能知道其所属的enum类。name()方法返回enum实例声明时的名字,这与使用toString()方法效果相同。valueOf()是在Enum中定义的static方法,它根据给定的名字返回相应的enum实例,如果不存在给定名字的实例,将会抛出异常。

values()的神秘之处

前面已经提到,编译器为你创建的enum类都继承自Enum类。然而,如果你研究一下Enum 类就会发现,它并没有values()方法。可我们明明已经用过该方法了,难道存在某种“隐藏的”方法吗?我们可以利用反射机制编写一个简单的程序,来查看其中的究竟∶

package enumerated;

import utils.OSExecute;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author Mr.Sun
 * @date 2022年09月02日 16:10
 *
 * 使用反射机制研究枚举类的values()
 */
enum Explore {
    HERE, THERE
}

public class Reflection {

    public static Set<String> analyze(Class<?> enumClass) {
        System.out.println("----- Analyzing " + enumClass + " -----");
        System.out.println("Interfaces:");
        for (Type t : enumClass.getGenericInterfaces()) {
            System.out.println(t);
        }
        System.out.println("Base: " + enumClass.getSuperclass());
        System.out.println("Methods: ");
        Set<String> methods = new TreeSet<String>();
        for (Method method : enumClass.getMethods()) {
            methods.add(method.getName());
        }
        System.out.println(methods);
        return methods;
    }

    public static void main(String[] args) {
        Set<String> exploreMethods = analyze(Explore.class);
        Set<String> enumMethods = analyze(Enum.class);
        System.out.println("Explore.containsAll(Enum)? " + exploreMethods.containsAll(enumMethods));
        System.out.print("Explore.removeAll(Enum): ");
        exploreMethods.removeAll(enumMethods);
        System.out.println(exploreMethods);
        // Decompile the code for the enum:
        OSExecute.command("javap G:/github/cnblogs/gitee/thinking-in-java/out/production/thinking-in-java/enumerated/Explore.class");
    }

} /* Output:
----- Analyzing class enumerated.Explore -----
Interfaces:
Base: class java.lang.Enum
Methods: 
[compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, values, wait]
----- Analyzing class java.lang.Enum -----
Interfaces:
java.lang.Comparable<E>
interface java.io.Serializable
Base: class java.lang.Object
Methods: 
[compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, wait]
Explore.containsAll(Enum)? true
Explore.removeAll(Enum): [values]
Compiled from "Reflection.java"
final class enumerated.Explore extends java.lang.Enum<enumerated.Explore> {
  public static final enumerated.Explore HERE;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值