Effective Java--读书笔记(六)【待完成】

第六章 枚举和注解

Java支持两种特殊用途的引用类型:一种是类,称作枚举类型;一种是接口,称作注解类型

第三十四条:用enum代替int常量

34.1 枚举类型简介

枚举类型是指有一组固定的常量组合成合法值的类型。

34.1.1 int枚举模式

之前,我们使用一组常量来表示枚举类型 int枚举模式

public static final int APPLE_FUJI =0;

如上不具有类型安全性,可读性极差。
这里注意每个apple常量是以APPLE_为前缀,每个orange常量是以ORANGE_为前缀。这是因为没有为int枚举模式提供命名空间。前缀可以防止发生冲突。
int枚举模式是编译时常量,它们的int值会被编译到使用它们的客户端上,如果int类型上的值发生了变化,客户端必须重新编译,客户端程序还是可以运行的,不过期行为已经不再明确。而且很难将int枚举常量打印成字符串,就算打印出来,也只是一个数字,没有什么作用。

34.1.2 String枚举模式

它提供了可打印的字符串。但是新手会直接把字符串硬编码到客户端代码中,而不是使用对应的常量字段名,一旦出现书写错误那么编译时将不会被检测到,就会报错。而且性能低,因为他会依靠String的比较操作。

34.1.3 枚举类型

Java的枚举本质上是int值。

34.1.3.1 基本思想

这些类通过公有的静态final域为每个枚举常量导出一个实例。
枚举类型没有可以访问的构造器,所以它是真正的final类。客户端不能创建枚举类型的实例,也不能对它进行扩展,因此不存在实例,而只存在声明过的枚举常量。
换句话说:枚举类型是实例受控的。它们是单例的泛型化,本质上是单元素的枚举。

34.1.3.2 枚举类型的优势

枚举类型保证了编译时的类型安全。例如试图将某种枚举类型的表达式赋给另一种枚举类型的变脸,或者试图利用==操作符比较不同枚举类型的值都会导致编译时错误。
包含同名常量的多个枚举类型可以在一个系统*存。因为每个命名都有自己的命名空间。你可以增加或者重新排列枚举类型中的常量,而无需重新编译它的客户端代码,因为到处常量的域在枚举类型和它的客户端之间提供了一个隔离层:常量并没有被编译到客户端代码中,而是在int枚举模式之中。最终,可以通过调用toString方法,将枚举转换成可打印的字符串。
除了完善int枚举模式的不足之处,枚举类型还允许添加任意方法和域,并实现任意的接口。它们提供了所有的Object方法的高级实现,实现了Comparable和Serializable接口,并针对枚举类型的可任意改变性设计了序列化方式。

34.2 枚举类型演示

/**
 * @author yuxingang
 * date 2020-12-25  14:58
 */
public enum Plant {
    MERCURY(3.302E+23, 2.439E6),
    VENUS(4.869E+24, 6.025E6),
    EARTH(5.975E+24, 6.378E6),
    MARS(6.419E+23, 3.393E6),
    JUPITER(1.899E+27, 7.149E7),
    SATURN(5.685E+26, 6.027E7),
    URANUS(8.683E+25, 2.556E7),
    NEPTUNE(1.024E+26, 2.477E7);
    private final double mass;//In KG
    private final double radius;//In meters
    private final double surfaceGravity;//
    private static final double G = 6.67300E-11;

    //Constructor
    Plant(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
        surfaceGravity = G * mass / (radius * radius);
    }

    public double mass() {
        return mass;
    }

    public double radius() {
        return radius;
    }

    public double surfaceGravity() {
        return surfaceGravity;
    }

    public double surfaceWeight(double mass) {
        return mass * surfaceGravity;
    }
}
上一篇:Android系统--输入系统(七)Reader_Dispatcher线程启动分析


下一篇:20165223 week6测试错题总结