第四章 类和接口 第15条 使可变性最小化

第15条:使可变性最小化

如何使类成为不可变的

  1. 不要提供任何会修改对象状态的方法   即setter
  2. 保证类不会被扩展 一般使这个类成为final的
  3. 使所有域都是final的
  4. 使所有域成为私有的
  5. 确保对于任何可变组件的互斥访问   readObject方法中使用保护性拷贝

public final class Complex {
	private final double re;
	private final double im;
	public Complex(double re, double im) {
		super();
		this.re = re;
		this.im = im;
	}
	
	public double realPart() {return re;}
	public double imaginaryPart() {return im;}
	
	//没有提供setter方法
	
	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(c.re * 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,(re * c.re - im * c.im)/tmp);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(im);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(re);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Complex other = (Complex) obj;
		if (Double.doubleToLongBits(im) != Double.doubleToLongBits(other.im))
			return false;
		if (Double.doubleToLongBits(re) != Double.doubleToLongBits(other.re))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Complex [re=" + re + ", im=" + im + "]";
	}
	
}

每次运算都返回新的Cpmplex实例,而不是修改这个实例,它被称为函数的做法

优点:

  1. 不可变对象本质上是线程安全的,它们不要求同步,不可变 对象可以被共享
  2. 不公可以共享对象,也可以共享他们的内部信息
  3. 不可变对象 为其它对象提供了大量的构件

缺点:

对于每一个值都需要一个单独的对象


还有一种更加灵活的方法:

public class ComplexOther {
	private final double re;
	private final double im;
	
	private ComplexOther(double re,double im) {
		this.re = re;
		this.im = im;
	}
	
	public static ComplexOther getInstance(double re,double im) {
		return new ComplexOther(re,im);
	}
}

这种方式的好处:

1.允许使用多个包级实现类

2.可以提供缓存能力

3.具有静态工厂的优势


阅读更多
个人分类: effective java
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭