第十五条 使可变性最小化


不可变的类是指这个类被实例化了后,不能被修改。类的成员变量必须是在创建的时候被赋值,并在对象被销毁钱不会改变。java 中的 String 基本类型包装类 BigInterger 等都属于这方面的例子
。这样设计的好处是 易于设计 不容易出错,更安全。我们设计这种类型的类时,要遵循五大原则:
一、不要提供任何可以改变成员变量值的方法。 也就是说这个类的成员变量,不要对外暴露方法,从而可以改变它的值,例如 setter方法 ;
二、保证类不会被扩展。 防止恶意创作一个子类,然后通过子类来改变父类的一些属性,final 就可以起作用,用它修饰类,就不能被继承了;
三、使所有的域都成为私有的。这句话的意思是 把成员变量和自己的方法,都使用 final 来修饰,作用如上一条,保证它们不能被修改;
四、使所有的域都成为私有的。 意思是 把成员变量和自己的方法,都使用 private 来修饰,这样,通过该类的对象就不能修改成员变量的值了;
五、确保对于任何可变组件的互斥访问。 这句话有点不好理解,一般情况用不到。一般来说,注意构造器 访问方法 和 readObject中使用保护性拷贝,可以重新创造一个对象,不要几个方法共同产
生一个对象。


public final class Complex {

        private final double re;
        private final double im;

        public Complex(double re, double im) {
            this.re = re;
            this.im = im;
        }

        public double realPart() { return re; }

        public double imaginaryPart() { return im; }

        public Complex plus(Complex c) {
            return new Complex(re + c.re, im + c.im);
        }

        public Complex minus(Complex c) {
            return new Complex(re - c.re, im - c.im);
        }

        public Complex times(Complex c) {
            return new Complex(re * c.re - im * c.im,
                    re * c.im + im * c.re);
        }

        public Complex dividedBy(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 47 to find out why we use compare instead of ==
            return Double.compare(c.re, re) == 0 && Double.compare(c.im, im) == 0;
        }

        @Override public int hashCode() {
            return 31 * Double.hashCode(re) + Double.hashCode(im);
        }

        @Override public String toString() {
            return "(" + re + " + " + im + "i)";
        }
    }

书上这个例子就很完美。这个类及成员变量和方法,都被 final 修饰,(除了从父类继承的公共方法)。该类不会被继承,没有set方法改变属性的值,传入一个对象,也是通过方法去构造一个新的对
象,即使几个方法同时调用,也不会返回相同的一个对象。Complex c1 = new Complex(1, 1); 如果觉得不方便,可以修改类,提供静态工厂方法。

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);
        }
    }

Complex c2 = Complex.valueOf(1, 1);

对外千万不要提供set和get方法,不要改变对象的值。这种写法好处多,当然也有坏处,就是可能会创造大量的对象,浪费性能。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值