第15条:使可变性最小化

  通过一个复数类来看不可变类。

public final class Complex {
private final double re;
private final double im; private Complex(double re, double im) {
this.re = re;
this.im = im;
} public static Complex valueOf(double re, double im) {
return new Complex(re, im);
} public static Complex valueOfPolar(double r, double theta) {
return new Complex(r * Math.cos(theta), r * Math.sin(theta));
} public static final Complex ZERO = new Complex(0, 0);
public static final Complex ONE = new Complex(1, 0);
public static final Complex I = new Complex(0, 1); public double realPart() {
return re;
} public double imaginaryPart() {
return im;
} public Complex add(Complex c) {
return new Complex(re + c.re, im + c.im);
} public Complex subtract(Complex c) {
return new Complex(re - c.re, im - c.im);
} public Complex multiply(Complex c) {
return new Complex(re * c.re - im * c.im, re * c.im + im * c.re);
} public Complex divide(Complex c) {
double tmp = c.re * c.re + c.im * c.im;
return new Complex((re * c.re + im * c.im) / tmp, (im * c.re - re
* c.im)
/ tmp);
} @Override
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Complex))
return false;
Complex c = (Complex) o; return Double.compare(re, c.re) == 0 && Double.compare(im, c.im) == 0;
} @Override
public int hashCode() {
int result = 17 + hashDouble(re);
result = 31 * result + hashDouble(im);
return result;
} private int hashDouble(double val) {
long longBits = Double.doubleToLongBits(re);
return (int) (longBits ^ (longBits >>> 32));
} @Override
public String toString() {
return "(" + re + " + " + im + "i)";
}
}

  复数类具有实部和虚部,它提供的加减乘除运算都是返回新的Complex实例,而不是修改这个实例。不可变对象有很多优点,它只有一种状态,即被创建时的状态,而且前面也提到过,它本质上是线程安全的。

  这里还用到一个小技巧,对频繁使用的值,为它们提供公有的静态final常量。

  还有一种构建不可变类的常用方法,让类的构造器私有化,并添加上公有静态工厂方法,前面也提到过。

  String类就是不可变类一个典型例子。但是细心的读者肯定会发现String类的hash属性不是final类型的,事实上,许多不可变类都拥有一个或多个非final的域,在第一次请求的时候计算出来缓存在这些域中,从而节约了计算所需要的花销。因为对象是不可变的,它的不可变性保证了计算结果相同。

public final class String{
private final char value[];
private int hash; public int hashCode() {
int h = hash;
//只有hash不存在时才去计算
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
}

第16条:复合优先于继承

  简而言之,只有当两者确实存在is-a的关系时,才使用继承。否则,都应该使用复合。对于这一条,应用最典型的例子就是设计模式中的装饰者模式

Effective Java2读书笔记-类和接口(二)的更多相关文章

  1. Effective Java2读书笔记-类和接口(一)

    第13条:使类和成员的可访问性最小化 设计良好的模块的模块与设计不好的模块区别在于,设计良好的模块会隐藏所有的实现细节,把它的API与他的实现清晰地隔离开来.然后模块之间只通过API通信. 信息隐藏之 ...

  2. Effective Java2读书笔记-类和接口(五)

    第21条:用函数对象表示策略 这一条其实也没说啥,就是策略模式.碰到这种场景时,定义一个策略接口,然后不同策略子类实现它,主类包含这个接口的引用就可以了. 第22条:优先考虑静态成员类 嵌套类是指被定 ...

  3. Effective Java2读书笔记-类和接口(四)

    第19条:接口只用于定义类型 这一条就举了一个反例,说有些接口中只包含常量.这是对接口的不良使用.要实现相同的功能,应该使用不可实例化的工具类(第4条说过). public class Physica ...

  4. Effective Java2读书笔记-类和接口(三)

    第17条:要么为继承而设计,并提供文档说明,要么就禁止继承 第18条:接口优于抽象类 这两条中,提到了一个很重要的概念骨架实现.也就是说,抽象类实现接口的形式.这样的好处是,接口本来不能提供默认的实现 ...

  5. Effective Java读书笔记--类和接口

    1.使类和成员的可访问性最小化不指定访问级别,就是包私有.protected = 包私有 + 子类一般private不会被访问到,如果实现了Serializable,可能会泄露.反射.final集合或 ...

  6. Effective Java2读书笔记-对于所有对象都通用的方法(二)

    第10条:始终要覆盖toString 这一条没什么好讲的,就是说默认的toString方法打印出来的是类名+@+十六进制哈希码的值.我们应该覆盖它,使它能够展示出一些更为详细清晰的信息,这个看实际情况 ...

  7. Effective Java2读书笔记-创建和销毁对象(二)

    第3条:用私有构造器或者枚举类型强化Singleton属性 这一条,总体来说,就是讲了一个小技巧,将构造器声明为private,可以实现单例.具体有以下几种实现的方式. ①最传统的单例实现模式,可能有 ...

  8. 《Java核心技术》 -- 读书笔记 ② - 类 | 对象 | 接口

    对象vs对象变量 “对象” 描述的是一个类的具体实例,他被java虚拟机分配在 "堆" (Heap)中. “对象变量” 为一个对象的引用(对象变量的值=记载着具体对象的位置/地址) ...

  9. Effective Java2读书笔记-对于所有对象都通用的方法(三)

    第12条:考虑实现Comparable接口 这一条非常简单.就是说,如果类实现了Comparable接口,覆盖comparaTo方法. 就可以使用Arrays.sort(a)对数组a进行排序. 它与e ...

随机推荐

  1. Android应用程序窗口(Activity)的窗口对象(Window) 的创建过程分析

    每一个Activity组件都有一个关联的ContextImpl对象,同时,它还关联有一个Window对象,用来描述一个具体的应用程序窗口. 每一个Activity组件都有一个关联的ContextImp ...

  2. bzoj4003

    http://www.lydsy.com/JudgeOnline/problem.php?id=4003 可合并堆. 每个点都有一个小根堆,记住可以到这个点的骑士有哪些,以战斗力为关键字. 从底层到顶 ...

  3. jquery判断checkbox是否选中

    $('input:checkbox').click(function () { if ($("#chkPile").is(":checked")) { $(); ...

  4. Jtree (节点的渲染+资源管理器)

    我们的还是自定义的Jtree的类: package jtree.customNode; import java.io.File; import javax.swing.JTree; import ja ...

  5. PyCharm 4.0下载(附keygen)

    百度网盘:http://pan.baidu.com/s/1nvAdEM9  密码:xfz9

  6. Webservice-Java-Xfire

    最近公司最近需要将以前提供出去的接口统一用一个标准来实现,考虑到webservice这个是标 准,因此我花时间大概学习了一下webservice,也对JAVA的几个webservice框架进行了一些小 ...

  7. [RxJS] Reactive Programming - New requests from refresh clicks -- merge()

    Now we want each time we click refresh button, we will get new group of users. So we need to get the ...

  8. Linux命令vi/vim编辑

    一.vi的基本概念基本上vi可以分为三种状态,分别是命令模式(command mode).插入模式(Insert mode)和底行模式(last line mode),各模式的功能区分如下:a) 命令 ...

  9. oracle卸载Oracle Clusterware(转载)

    1.脚本自动删除 切换到root用户 $Su – root #cd $ORA_CRS_HOME/install 1.执行rootdelete.sh脚本 # ./rootdelete.sh 2.执行ro ...

  10. 深入解析MySQL replication协议

    Why 最开始的时候,go-mysql只是简单的抽象mixer的代码,提供一个基本的mysql driver以及proxy framework,但做到后面,笔者突然觉得,既然研究了这么久mysql c ...