第30条:用enum代替int常量
枚举类型对比int枚举,String枚举等
- 易读(不同枚举可以包含同名等)
- 更加安全(不同枚举值不可以互操作)
- 功能更加强大(可以添加任意的方法和域,并实现任意接口,为了将数据与枚举常量关联起来,得声明实例域,并编写一个带有数据并将数据保存在域中的构造器)
可以将数据与枚举常量关联起来,得声明实例域,并编写一个带有数据并将数据保存在域中的构造器
可以将不同行为与每个枚举常量关联起来,特定于常量的类主体
如果多个枚举常量同时共享相同的行为,则考虑策略枚举,而不是switch
枚举中的switch语句适合于给外部的枚举类型增加特定于常量的行为。如针对Operation的每个操作返回相反的操作
// Enum type with constant-specific method implementations
public enum Operation {
PLUS { double apply(double x, double y){return x + y;} },
MINUS { double apply(double x, double y){return x - y;} },
TIMES { double apply(double x, double y){return x * y;} },
DIVIDE { double apply(double x, double y){return x / y;} };
abstract double apply(double x, double y);
}
第31条:用实例域代替序数
永远不要根据枚举的序数导出与它关联的值,而是要将它保存在一个实例域中。
// Abuse of ordinal to derive an associated value - DON'T DO THIS
public enum Ensemble {
SOLO, DUET, TRIO, QUARTET, QUINTET,
SEXTET, SEPTET, OCTET, NONET, DECTET;
public int numberOfMusicians() { return ordinal() + 1; }
}
应该这样用,比较好
public enum Ensemble {
SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5),
SEXTET(6), SEPTET(7), OCTET(8), DOUBLE_QUARTET(8),
NONET(9), DECTET(10), TRIPLE_QUARTET(12);
private final int numberOfMusicians;
Ensemble(int size) { this.numberOfMusicians = size; }
public int numberOfMusicians() { return numberOfMusicians; }
}
第32条:用EnumSet代替位域
EnumSet可以代替位算法来传递丰富的参数,如下例子用EnumSet来设置Text的style
// EnumSet - a modern replacement for bit fields
public class Text {
public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }
// Any Set could be passed in, but EnumSet is clearly best
public void applyStyles(Set<Style> styles) { ... }
}
将EnumSet实力传递给applyStyle这个方法的接口参数
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));
总结:正式因为枚举类型要用在集合(Set)中,所以没有理由用位域来表示它。
第33条:用EnumMap代替序数索引
有时候会看见用ordinal方法来索引数组的代码,如:
public class Herb {
public enum Type { ANNUAL, PERENNIAL, BIENNIAL }
private final String name;
private final Type type;
Herb(String name, Type type) {
this.name = name;
this.type = type;
}
@Override public String toString() {
return name;
}
}
// Using ordinal() to index an array - DON'T DO THIS!
Herb[] garden = ... ;
Set<Herb>[] herbsByType = // Indexed by Herb.Type.ordinal()
(Set<Herb>[]) new Set[Herb.Type.values().length];
for (int i = 0; i < herbsByType.length; i++)
herbsByType[i] = new HashSet<Herb>();
for (Herb h : garden)
herbsByType[h.type.ordinal()].add(h);
// Print the results
for (int i = 0; i < herbsByType.length; i++) {
System.out.printf("%s: %s%n",
Herb.Type.values()[i], herbsByType[i]);
}
这种方法虽然的确可行,但是隐藏这许多问题,数组不知道它的索引代表着什么,你必须手工标注这些索引的输出。但是按照枚举的顺序进行索引数组的时候,int不能提供枚举的类型安全。
这时候需要使用EnumMap,快速实现枚举值映射
// Using an EnumMap to associate data with an enum
Map<Herb.Type, Set<Herb>> herbsByType =
new EnumMap<Herb.Type, Set<Herb>>(Herb.Type.class);
for (Herb.Type t : Herb.Type.values())
herbsByType.put(t, new HashSet<Herb>());
for (Herb h : garden)
herbsByType.get(h.type).add(h);
System.out.println(herbsByType);
同样进行多次索引(数组的数组),道理是一样的
总而言之,最好要用序数来索引数组,而要是有EnumMap。
多维的汝EnumMap<..., EnumMap<...>>
第34条:用接口模拟可伸缩的枚举
虽然无法编写可扩展的枚举类型,却可以通过编写接口以及实现该接口的基础枚举类型,对它进行模拟。
如对于操作Operation,在基本操作枚举已有的情况下,假如需要添加更多的操作,可以编写扩展的枚举来实现这个接口,针对基础枚举的API是根据接口来编写的,对扩展的枚举同样适用。
基础的Operation
// Emulated extensible enum using an interface
public interface Operation {
double apply(double x, double y);
}
public enum BasicOperation implements Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
public double apply(double x, double y) { return x / y; }
};
private final String symbol;
BasicOperation(String symbol) {
this.symbol = symbol;
}
@Override public String toString() {
return symbol;
}
}
扩展的Operation
// Emulated extension enum
public enum ExtendedOperation implements Operation {
EXP("^") {
public double apply(double x, double y) {
return Math.pow(x, y);
}
},
REMAINDER("%") {
public double apply(double x, double y) {
return x % y;
}
};
private final String symbol;
ExtendedOperation(String symbol) {
this.symbol = symbol;
}
@Override public String toString() {
return symbol;
}
}
第35条:注解优先于命名模式
目前使用很少,没有什么深刻体会,理解不透
第36条:坚持使用Override注解
在你想要覆盖超类声明的每个方法中声明使用Override注解,这样编译器就会帮助你发现是否正确覆盖了一个方法。
例外:在具体的类中,不必标注你确信覆盖了的抽象的方法;实现接口的类中,也不必标注出你想要哪些方法来覆盖接口方法,这两种情况编译器都会帮助你提醒,没有覆盖,抛出错误。当然标注了也没有什么坏处。
但是在抽象类和接口覆盖超类或者超接口的时候,坚持使用Override注解
第37条:用标记接口定义类型
不知所云
上一条:Effective Java 2 读书笔记 第6章 枚举和注解
分享到:
相关推荐
"Effective Java读书笔记" Effective Java是一本关于Java编程语言的经典书籍,本笔记主要总结了Java语言的发展历程、静态工厂方法的应用、构造器模式的使用等重要知识点。 一、Java语言的发展历程 Java语言的发展...
《Effective Java》是Java开发领域的经典著作,作者Joshua Bloch深入浅出地阐述了编写高效、健壮的Java代码的技巧和最佳实践。以下是对该书部分内容的详细解释: 1. **产生和销毁对象** - Item1:静态工厂方法相比...
Effective Java 读书笔记 - 枚举与注解 本文总结了Effective Java 中关于枚举与注解的知识点,涵盖了枚举类型的优点、使用指南、避免使用 int 常量、使用 EnumSet 和 EnumMap 等。 枚举类型的优点 枚举类型提供了...
其他知识点还包括泛型、枚举和注解、Lambda 和 Stream、方法、通用编程、异常、并发、序列化等。这些知识点都是 Java 编程语言的核心内容,了解和掌握这些知识点对于编写高质量的 Java 代码至关重要。 《Effective ...
《Effective Java》是Java...以上仅是《Effective Java》一书中部分核心知识点的概述,实际的读书笔记中会更详细地解释这些概念,并给出具体的示例代码。通过深入学习和实践,开发者可以极大地提升其Java编程的水平。
### 第六章 实例域 讨论实例域的初始化、可见性、并发访问等,以及如何设计线程安全的类。 ### 第七章 类的复用 涵盖类和接口的复用策略,如组合优于继承、接口优于抽象类等。 ### 第八章 并发 讨论Java并发工具和...
根据给定的文件信息,以下是对“精版Effective STL读书笔记”的详细解析,重点提炼了STL(标准模板库)中的关键知识点。 ### 标题:“精版Effective STL读书笔记” 此标题暗示了文档是针对《Effective STL》一书的...
### Effective Java读书笔记(上) #### 第一章 引言 本书主要针对Java开发者提供了大量实用的编程指导建议,帮助读者提升代码质量和程序性能。在本章节中,我们将重点介绍对象的创建与销毁,以及一些重要的设计...
读书笔记:Effective Java中文版第3版笔记
这本书的第三版包含了大量更新,涵盖了Java语言和平台的新发展,如Java 8和Java 9的新特性。以下是对《Effective Java》笔记中可能涉及的关键知识点的详细解读: 1. **单例模式**:书中强调了如何正确实现单例模式...
读书笔记:Effective Java中文版 第2版
读书笔记:Effective Java 中文版(2版和3版)
从给出的部分内容来看,读书笔记主要聚焦于以下几个知识点: 1. C++语言的联邦概念:C++是一个由多个次语言构成的语言联邦,这包括了C语言核心、面向对象的C++、模板C++以及标准模板库(STL)。这种理解对于深入...
读书笔记:Effective Java中文版学习项目
4. **第6章 枚举和注解** - 枚举的使用:强调枚举的多种用途,如枚举类型的安全性、枚举实例的遍历、枚举常量的关联方法等。 - 注解:解释注解的元数据功能,如何创建自定义注解以及处理注解的反射API。 5. **第7...
读书笔记:Effective Java中文版第二版示例、笔记
读书笔记:Java练习包括《Java编程思想》《算法》《Effective Java》等
读书笔记:Effective Java中文版第二版示例代码
标题“effective-java.pdf”与描述“effective-java.pdf”表明本文档是关于Java编程实践的指南,且内容可能来自于一本名为《Effective Java》的书籍,该书是由Joshua Bloch编写,被广泛认为是Java编程的权威指南。...