Effective Java 15 Minimize mutability
Use immutable classes as much as possible instead of mutable classes.
Advantage
- Easy to design, implement and use than mutable classes.
- Less prone to error and more secure.
- Immutable objects are simple.
- Immutable objects are inherently thread-safe; they require no synchronization.
- Immutable objects and their internals can be shared freely between threads.
- Immutable calss can provide static factories that cache frequently requested instances to avoid creating new instances.
- Immutable objects make great building blocks for other objects.(eg. Use immutable object as the key of map or set colletion)
Disadvantage
Immutable classes require a separate object for each distinct value which may be costly.
Principles:
- Don't provide any methods that modify the object's state.
- Ensure that the class can't be extended.
- Make all fields final.
- Make all fields private.
/**
* Example code for Minimize mutability
*/
package com.effectivejava.classinterface;
/**
* @author Kaibo
*
*/
public final class Complex {
private final double re;
private final double im;
public Complex(double re, double im) {
this.re = re;
this.im = im;
}
// Accessors with no corresponding mutators
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;
// See page 43 to find out why we use compare instead of ==
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)";
}
/**
* @param args
*/
public static void main(String[] args) {
Complex c1 = new Complex(1.0, 2.0);
Complex c2 = new Complex(1.0, 2.0);
Complex c3 = new Complex(3.0,4.0);
System.out.printf("c1.equals(c2) = %s%n", c1.equals(c2));
System.out.printf("c1.equals(c3) = %s%n",c1.equals(c3));
System.out.printf("c1 + c2 = %s%n", c1.add(c2));
System.out.printf("c1 - c2 = %s%n", c1.subtract(c2));
System.out.printf("c1 * c2 = %s%n", c1.multiply(c2));
System.out.printf("c1 / c2 = %s%n", c1.divide(c2));
}
}
Note:
You can use alternative immutable implementation to not permit class to be subclassed instead of use final decorate to the class. Just use the static factory method and private constructor to constrain this which enable the client outside the package to use this class freely and providing the extensibility for caching.
// Immutable class with static factories instead of constructors
public 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));
}
... // Remainder unchanged
}
BigInteger and BigDecimal are not final
If you write a class whose security depends on the immutability of a BigInteger or BigDecimal argument from an untrusted client, you must check to see that the argument is a "real" BigInteger or BigDecimal, rather than an instance of an untrusted subclass. If it is the latter, you must defensively copy it under the assumption that it might be mutable (Item 39)
public static BigInteger safeInstance(BigInteger val) {
if (val.getClass() != BigInteger.class)
return new BigInteger(val.toByteArray());
return val;
}
Serializability.
If you choose to have your immutable class implement Serializable and it contains one or more fields that refer to mutable objects, you must provide an explicit readObject or readResolve method, or use the ObjectOutputStream.writeUnshared and ObjectInputStream.readUnsharedmethods, even if the default serialized form is acceptable. Otherwise an attacker could create a mutable instance of your not quite-immutable class. This topic is covered in detail in Item76.
Summary
If a class cannot be made immutable, limit its mutability as much as possible. make every field final unless there is a compelling reason to make it non-final.
Effective Java 15 Minimize mutability的更多相关文章
- Effective Java 13 Minimize the accessibility of classes and members
Information hiding is important for many reasons, most of which stem from the fact that it decouples ...
- Effective Java 45 Minimize the scope of local variables
Principle The most powerful technique for minimizing the scope of a local variable is to declare it ...
- Effective Java Index
Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...
- 《Effective Java》读书笔记 - 4.类和接口
Chapter 4 Classes and Interfaces Item 13: Minimize the accessibility of classes and members 一个好的模块设计 ...
- Effective Java 第三版——15. 使类和成员的可访问性最小化
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java Chapter4 Classes and Interface
MInimize the accessibility of classes and members 这个叫做所谓的 information hiding ,这么做在于让程序耦合度更低,增加程序的健壮性 ...
- Effective Java 目录
<Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...
- 【Effective Java】阅读
Java写了很多年,很惭愧,直到最近才读了这本经典之作<Effective Java>,按自己的理解总结下,有些可能还不够深刻 一.Creating and Destroying Obje ...
- Effective Java通俗理解(持续更新)
这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...
随机推荐
- Android 学习笔记多媒体技术之 AsyncTask+实现音频播放...
PS:今天搞了一下如何实现音频播放...结果被坑了,看书上写的代码是挺简单的,但是有个函数就是死活没看懂,这真是受不了...最后才弄明白,原来是一个实现异步任务的一个类...这个类使用java.uti ...
- Java工程师面试题,整理自网络与博主各种笔试面试,持续更新
1.面向对象的特征有哪些方面? 封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口. 多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应.简单的说就是用同 ...
- 二维KMP - 求字符矩阵的最小覆盖矩阵 - poj 2185
Milking Grid Problem's Link:http://poj.org/problem?id=2185 Mean: 给你一个n*m的字符矩阵,让你求这个字符矩阵的最小覆盖矩阵,输出这个最 ...
- Chrome弹窗的简单应用(选择结构与循环结构)
★选择结构★ ★JS实现弹窗显示随机数 示例代码效果图 ★ 弹窗实现对随机数的进一步判断 示例代码效果图 ★综合应用 比较大小 ★ 判断成绩等级 ): : : : : alert(" ...
- PHP验证邮箱地址代码
PHP验证邮箱代码: function isEmail($email) { return strlen($email) > 6 && preg_match("/^[\w ...
- 创建Google网站地图Sitemap.xml
Sitemap.xml是google搞出来的,也就是网站地图,不过这个网站地图是用xml写的,而且要按google的标准来写,并且要将写出来的这个文件sitemap.xml上传到自己的服务器空间中去. ...
- 不可或缺 Windows Native (7) - C 语言: 指针
[源码下载] 不可或缺 Windows Native (7) - C 语言: 指针 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 指针 示例cPointer.h #i ...
- 重新想象 Windows 8.1 Store Apps (91) - 后台任务的新特性: 下载和上传的新特性, 程序启动前预下载网络资源, 后台任务的其它新特性
[源码下载] 重新想象 Windows 8.1 Store Apps (91) - 后台任务的新特性: 下载和上传的新特性, 程序启动前预下载网络资源, 后台任务的其它新特性 作者:webabcd 介 ...
- MySQL更新优化
通常情况下,当访问某张表的时候,读取者首先必须获取该表的锁,如果有写入操作到达,那么写入者一直等待读取者完成操作(查询开始之后就不能中断,因此允许读取者完成操作).当读取者完成对表的操作的时候,锁就会 ...
- python代码风格-PEP8
转载自http://www.douban.com/note/134971609/ Python 的代码风格由 PEP 8 描述.这个文档描述了 Python 编程风格的方方面面.在遵守这个文档的条件下 ...