Effective Java其他碎片建议2
来源:互联网 发布:手机能申请淘宝店铺吗 编辑:程序博客网 时间:2024/05/22 12:36
Rule 15、使可变性最小化
为了使类成为不可变,遵循以下五条规则:
1、不要提供任何会改变对象状态的方法(也称为mutator)
2、保证类不会被扩展(一般是使用final关键字修饰类 但是也有其他的方法)
3、使所有域都是final的
4、使所有域都是私有的
5、确保对于任何可变组件的互斥访问(保证类的客户端无法获取指向这些对象的引用(使用保护性拷贝))
不可变对象本质上是线程安全的,他们不要求同步。
不可变对象真正唯一的缺点是,对于每个不同的值都需要一个单独的对象。
Rule 16、复合优先于继承
继承是实现代码重用的有力手段,但不一定是最好的。
继承打破了子类的封装性。当子类真正是超类的子类型(subtype)时,才适合用继承(is-a)。
有时候,B应该包含A一个私有实例,并且暴露出一个简单的、较小的API,A本质上不是B的一部分,这就不该用继承,而是复合。
然而sun公司的大师们也会犯这样的错误,比如stack不是vector,所以Stack不应该扩展Vector;Properties也不是Hashtable,Properties就不应该扩展Hashtable,这样情况下,复合要好一点。
如果在应该使用复合的地方使用了继承,则会不必要地暴露实现细节。客户端就有可能直接访问这些内部细节。比如p指向了Properties实例,p.getProperties(key)就可能产生和p.get(key)不同的结果。
Rule 17、要么为继承设计并且提供文档说明,要么就禁止继承
如题,文档应该精确地描述覆盖每个方法带来的影响,换句话说,该类必须有文档说明它可覆盖的方法的自用性。
Rule 18、接口优先于抽象类
首先看看接口和抽象类的区别:抽象类允许包含某些方法的实现,但是接口则不允许。更重要的一点在于,如果想实现抽象类定义的类型,类必须成为抽象类的一个子类,然而java是单继承的。
接口是定义混合类型(mixin)的理想选择;
接口允许我们构造非层级结构的类型框架,而不是使用继承抽象类的臃肿的类层次;
Rule 19、接口只用于定义类型
当类实现接口时,接口就充当可以应用这个类的实例的类型。因此类实现了接口就表明客户端可以对这个类的实例实施某些操作,而出于其他任何目的定义接口都是在耍流氓。
有种接口叫做常量接口(constant interface),他没有任何的方法,只包含静态final域,每个域导出一个常量:
public interface Boy{ static final int AGE = 19; static final String LOCATION = "DLUT";}这是对接口的不良使用。类实现常量接口,这完全是对接口的滥用,会导致接口中的实现细节透露到导出API中,类实现常量接口对这个类的用户来讲没什么价值,而且容易给用户造成困惑。
如果就是想要实现类似的功能,可以利用静态导入(static import)机制:
import static 包名.*;//导入包名下的常量public class Test{ //访问}简而言之,接口应该只被用来定义类型。
Rule 20、类层次优于标签类
有时候,可能会遇到带有两种甚至更多风格的实例的类,并包含表示实例风格的标签(tag)域,比如下面的代码:
class Figure{ enum Shape{RECTANGLE,CIRCLE}; //tag field - the shape of this figure final Shape shape; //These fields are used only if shape is RECTANGLE double length; double width; //this field is used only if shape is CIRCLE double radius; //Constructor for circle Figure(double radius){ shape = Shape.CIRCLE; this.radius = radius; } //Constructor for rectangle Figure(double length,double width){ shape = Shape.RECTANGLE; this.length = length; this.width = width; } double area(){ switch(shape){ case RECTANGLE: return length * width; case CIRCLE: return Math.PI * (radius * radius); default: throw new AssertionError(); } }}
他们充斥着样板代码,包括枚举类型、标签域以及条件语句。可读性很糟糕,还增加了内存占用。总之,标签类冗长、容易出错、效率低下。我们可以使用类层次来解决这个问题,比如使用一个形状类Figure,使用Circle、Rectangle分别继承这个形状类Figure,可以更清楚地解决这个问题。
未完待续...
- Effective Java其他碎片建议2
- Effective Java其他碎片建议1
- Effective Java其他碎片建议3
- 《Effective Java》中的建议
- Effective Java中的57条建议
- Effective Java中的57条建议
- 《Effective Java》的前26条建议
- 《Effective Java》经典建议系列(3)
- 【Effective Java】最佳实践 其他合集
- Effective Java中对于实现高质量equals的建议
- 《Effective Java》中关于异常处理的几条建议
- java碎片
- JAVA碎片
- Effective STL 建议
- Effective Java 2
- Effective Java笔记 (2)
- Effective java读书笔记2
- Effective Java----2
- 第12周项目5-拓扑排序算法的验证
- JAVA作业11-16
- 数据结构上机实践第11周项目2
- 第九周项目2
- HTML5与CSS3
- Effective Java其他碎片建议2
- 利用NPAPI开发Chrome插件
- redis哈希相关命令
- PHPSTORM插件
- 第七周项目三
- 【数据库】FaceDataset常用的人脸数据库
- LeetCode-105:Construct Binary Tree from Preorder and Inorder Traversal (利用先序和中序遍历构建二叉树) -- medium
- JQuery基础笔记
- 大数据早报:Facebook宣布加入Open Media开源影音联盟 Bossa Nova融资1750万美元 (11.16)