Effective Java 阅读笔记——枚举和注解
30:用enum代替int常量
当需要一组固定常量的时候,应该使用enum代替int常量,除了对于手机登资源有限的设备应该酌情考虑enum的性能弱势之外。
31:用实例域代替序数
应该给enum添加int域,而不是使用ordinal方法来导出与枚举关联的序数值。(几乎不应使用ordinal方法,除非在编写像EnumMap这样的基于枚举的通用数据结构)
//WRONG
public enum Fruit{
APPLE, PEAR, ORANGE;
public int numberOfFruit(){
return ordinal() + 1;
}
} //RIGHT
public enum Fruit{
APPLE(1), PEAR(2), ORANGE(3);
private final int number;
Fruit(int num) {number = num;}
public int numberOfFruit(){
return number;
}
}
32:用EnumSet代替位域
EnumSet的内容都表示为位矢量。如若底层的枚举类型个数小于64个,则整个EnumSet就用单个long来表示,因此性能上比的上位域。
//WRONG
public class Text{
private static final int STYLE_BOLD = 1 << 0;
private static final int STYLE_ITALIC = 1 << 1;
private static final int STYLE_UNDERLINE = 1 << 2; public void applyStyles(int styles) {...}
}
//use
text.applyStyles(STYLE_BOLD | STYLE_ITALIC); //RIGHT
public class Text{
public enum Style{STYLE_BOLD, STYLE_ITALIC, STYLE_UNDERLINE} public void applyStyles(Set<Style> styles) {...} //这里不使用EnumSet<Style>参数是因为考虑到某些客户端可能会传递一些其他的Set实现
}
//use
text.applyStyles(EnumSet.of(STYLE_BOLD, STYLE_ITALIC));
33:用EnumMap代替序数索引
序数索引是指依赖于枚举成员在枚举中的序数来进行数组索引,如:
//定义了植物类,其中植物又分为水果,蔬菜,树木三种
public class Plant{
public enum Type { Fruit, Vegetables, Tree}
private final String name;
private final Type type; Plant(String name, Type type){
this.name = name;
this.type = type;
}
} Set<Plant>[] plants = (Set<Plant>[]) new Set[Plant.Type.valuse().lenght];
//根据植物的类型,分别把所有的植物放入三个set中
for(int i = 0; i < plant.lenght; i++){
plant[i] = new HashSet<Plant>();
} for(Plant p : garden){ //garden里放了所有的植物
plant[p.type.ordinal()].add(p) //反面教材:利用了枚举的序数来得到想要的数组索引,用户在其他地方可以不使用ordinal函数,而直接使用int值来访问,就可能出错
}
应该使用EnumMap来实现,EnumMap内部是采用数组实现的,具有Map的丰富功能和类型安全以及数组 的效率:
Map<Plant.Type, Set<Plant>> plants = new EnumMap<Plant.Type, Set<Plant>>(Plant.Type.class); //构造函数需要 键 类型的Class对象
//根据植物的类型,分别把所有的植物放入三个set中
for(Plant.Type type : Plant.Type.valuse()){
plant.put(type, new HashSet<Plant>);
} for(Plant p : garden){ //garden里放了所有的植物
plant.get(p.type).add(p) //用户必须使用正确的键值来访问,即Type类型
}
当需要多维关系时,可以使用EnumMap<..., EnumMap<...>>
34:用接口模拟可以伸缩的枚举
由于在java中enum不是可扩展的,在某些情况下,可能需要对枚举进行扩展,比如操作类型(+-*/等),就可以考虑:
- 定义一个接口,比如public interface Operation{...};
- 使枚举继承接口:比如public enum BasicOperation implements Operation{...}
- 使用时的API写成接口(比如,T extends Enum<T> & Operation),而不是实现(比如BasicOperation )
private static <T extends Enum<T> & Operation> void function(T t,..); //表示T即表示枚举又是Operation的子类型
- 当需要扩展BasicOperation枚举时,就可以另写一个枚举,且implements接口Operation
35:注解优先于命名模式
优先使用注解来表面针对某些程序元素的特定信息
36:坚持使用Override注解
在想要覆盖的方法上使用Override注解,编译器就可以帮助发现一些错误。可以不写Override的特例:在非抽象类中实现了父类的抽象方法,因为要是没有覆盖,则编译器就会发出错误。
37:用标记接口实现类型
标记分为标记接口和标记注解。
标记接口:没有包含方法声明的接口,只是指明某个类实现了具有某种属性的接口。比如Serializable接口。
标记接口与标记注解的最终要的区别在于:标记接口可以在编译时就检查到相应的类型问题,而标记注解则要到运行时。
使用:当标记要应用到任何程序元素,包括方法、域等,而不仅仅是接口和类,或者在未来会给标注添加更多信息,或者要适应已经广泛使用注解类型的框架,那么应该使用标记注解;当标记只应用给类和接口,定义一个任何新方法都不会与之关联的标记类型,就应该使用标记接口。
Effective Java 阅读笔记——枚举和注解的更多相关文章
- Effective Java阅读笔记——引言
“我很希望10年前就拥有这本书.可能有人认为我不需要任何Java方面的书籍,但是我需要这本书.” ——Java之父 James Gosling 在图书馆找到这本java著作时,首先看到了这句话. ...
- Effective Java 阅读笔记——方法
38:检查参数的有效性 每当编写方法或者构造器的时候,应该考虑它的参数有哪些限制,在方法的开头处对参数进行检查,并且把这些限制写入文档. 注意: 对于公有方法,应该使用@throws标签在文档中说明违 ...
- Effective Java 阅读笔记——并发
66:同步访问共享的可变数据 synchronized:1互斥,阻止线程看到的对象处于不一致的状态:2保证线程在进入同步区时能看到变量的被各个线程的所有修改 Java中,除了long或者double, ...
- 《Effective Java》笔记45-56:通用程序设计
将局部变量的作用域最小化,可以增强代码的可读性和可维护性,并降低出错的可能性. 要使用局部变量的作用域最小化,最有力的方法就是在第一次使用它的地方才声明,不要过早的声明. 局部变量的作用域从它被声明的 ...
- 【转】Java基础笔记 – 枚举类型的使用介绍和静态导入--不错
原文网址:http://www.itzhai.com/java-based-notes-introduction-and-use-of-an-enumeration-type-static-impor ...
- 《Effective Java》学习笔记 —— 枚举、注解与方法
Java的枚举.注解与方法... 第30条 用枚举代替int常量 第31条 用实例域代替序数 可以考虑定义一个final int 代替枚举中的 ordinal() 方法. 第32条 用EnumSet代 ...
- Effective java读书笔记
2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己 计在16年要看12本书,主要涉及java基础.Spring研究.java并发.J ...
- Effective Java读书笔记完结啦
Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. ...
- Effective Java 第三版——39. 注解优于命名模式
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
随机推荐
- SNF开发平台WinForm之三-开发-单表选择控件创建-SNF快速开发平台3.3-Spring.Net.Framework
3.1运行效果: 3.2开发实现: 3.2.1 这个开发与第一个开发操作步骤是一致的,不同之处就是在生成完代码之后,留下如下圈红程序,其它删除. 第一个开发地址:开发-单表表格编辑管理页面 http: ...
- Java知多少(111)数据库之修改记录
修改数据表记录也有3种方案. 一.使用Statement对象 实现修改数据表记录的SQL语句的语法是: update表名 set 字段名1 = 字段值1,字段名2 = 字段值2,……where特 ...
- Linux高级编程--09.线程互斥与同步
多个线程同时访问共享数据时可能会冲突,比如两个线程都要把某个全局变量增加1,这个操作在某平台需要三条指令完成: 从内存读变量值到寄存器 寄存器的值加1 将寄存器的值写回内存 假设两个线程在多处理器平台 ...
- centos 一键安装jdk
先检查 yum list installed |grep java 卸载JDK相关文件输入:yum -y remove java-1.7.0-openjdk*. 卸载tzdata-java输入:yum ...
- Eclipse中使用Junit编写测试用例
Eclipse自带Junit插件,不用安装就能在项目中编写测试用例,非常方便. 在项目中添加Junit库 在编写测试用例之前,需要先引入Junit.对项目根目录右键,选择Properties,Java ...
- 使用 IntelliJ IDEA 2016和Maven创建Java Web项目的详细步骤及相关问题解决办法
Maven简介 相对于传统的项目,Maven 下管理和构建的项目真的非常好用和简单,所以这里也强调下,尽量使用此类工具进行项目构建, 它可以管理项目的整个生命周期. 可以通过其命令做所有相关的工作,其 ...
- NodeJS+Mongodb+Express做CMS博客系统
楼主正在用业余时间开发中-- ,目前的版本仅支持会员系统,尝鲜一下吧~ hi-blog 一个 nodejs+express+mongodb 的 cms 系统 怎么启动 默认你已经安装了 mongodb ...
- Qt Style Sheet实践(三):QCheckBox和QRadioButton
导读 单选按钮(QRadioButton)和复选框(QCheckBox)是界面设计中的重要元素.单选按钮只允许用户在一组选项中选择一个,且当其中一个被选中的时候,按钮组中的其他单选按钮自动取消.复选框 ...
- 重构第17天提取父类(Extract SuperClass)
今天的重构来自 Martin Fowler的http://refactoring.com/catalog/extractSuperclass.html. 理解:本文中的“提取父类”是指类中有一些字段或 ...
- 使用BOM 的window对象属性打开新窗口
★ 示例1 要求:弹出新窗口,并向新窗口写入动态HTML代码 代码 <buttononclick="btnOpen()">打开新窗口</button> & ...