Effective Java 类和接口 15.使可变性最小化

不可变类只是其实例不能修改的类。每个实例中包含的所有信息都必须在创建该实例的时候提供,并在对象的整个生命周期内固定不变。

Java平台类库中包含许多不可变的类,其中就有String,基本类型的包装类。BigInteger和BidDdcimal。

存在不可变的类有有许多理由:(相对于可变的类)
1.容易设计,实现和使用,
2.不容出错,且更加安全。

实现不可变类需要遵守以下规则:

1.不要提供任何会修改对象状态的方法。
2.保证类不会被扩展
3.使所有的域都是final。
4.是所有的域都是私有的
5.确保对于任何可变组件的互斥访问。
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 iml;}

    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.re+im*c.im);
    }
    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)x;
    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+"");
    }
}

不可变类的优点:
1.不可变类对象比较简单。
2.不可变对象本质上是线程安全的,它们不要求同步。
例如:

        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);
    这种方法可以被进一步扩展。不可变的类可以提供一些静态工厂,它们把频繁被请求的实例缓存起来,从而当现有实例可以符合请求的时候,就不必创建新的实例。
3.”不可变对象可以被自由的共享“导致的结果,永远也不需要进行保护性拷贝。
4.不仅可以共享不可变对象,甚至也可以共享他们的内部信息
5.不可变对象为其他对象提供了大量的构件,无论是可变还是不可变的对象。

不可变类真正唯一的缺点是,对于每个不同的值都需要一个单独的对象。创建这种对象的代价很高,特别是对于大型对象的情形。

不可变类变成final的另一种办法就是,静态工厂方法。

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 static Complex valueOf(double re,double im){
        return new Complex(re,im);
    }
    ...
}

虽然这种方法并不常用,但他经常是最好的代替方法。

猜你喜欢

转载自blog.csdn.net/weixin_39923324/article/details/78081750
今日推荐