Effective Java读书笔记(三)

使类和成员的可访问性最小化

实例域决不能是公有的。如果域是非final的,或者是指向可变对象的final引用,那么一旦是这个域编程共有的,就放弃了对存储在这个域中的值进行限制的能力;这意味着,你也放弃了强制这个域不可变的能力。同时,当这个域被又该的时候,你也市区了对它采取任何行动的能力。因此,包含公有可变域的类并不是线程安全的

长度非零的数组总是可变的。

// Potential security hole!
public static final Thing[] VALUES = { ... };

有两种方法改善。

private static final Thing[] PRIVATE_VALUES = { ... };

public static final List<Thing> PRIVATE_VALUES = 
    Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));

public static final Thing[] values() {
    return PRIVATE_VALUES.clone();
}

在共有类中使用访问方法而非公有域

  • 如果类可以在它所在的包外部进行访问,就提供访问方法。
  • 如果类是包级私有的,或者是私有的嵌套类,直接暴露它的数据域并没有本质的错误。
  • 如果域是不可变的,直接暴露域的危害比较小。
// Public class with exposed immutable fields - questionable
public final class Time {
    private static final int HOURS_PER_DAY = 24;
    private static final int MINUTES_PER_HOUR = 60;

    public final int hour;
    public final int minutes;

    public Time(int hour, int minute) {
        if(hour < 0 || hour >=HOURS_PER_DAY) 
            throw new IllegalArgumentException("Hour: " + hour);
        if(minute < 0 || minute >= MINUTES_PER_HOUR)
            throw new IllegalArgumentException("Min: " + minute);
        this.hour = hour;
        this.minute = minute;
    }
    ... // Remainder omitted
}

使可变性最小化

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

  1. 不提供任何会修改对象状态的方法;
  2. 保证类不会被扩展。一般做法是使这个类成为final的。
  3. 使所有的域都是final的。
  4. 使所有的域都成为私有的。
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 coresponding 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 substract(Complex c){
        return new Complex(re - c.re, im - c.im);
    }

    // ...
}
  • 不可变对象比较简单,它只有一种状态,即被创建时的状态。
  • 不可变对象本质上是线程安全的,它们不要求同步。所以,不可变对象可以被自由的共享。所以,不可变类可以提供一些静态工厂,把频繁被请求的实例缓存起来,从而当现有实例可以符合请求的时候,就不必创建新的实例。

除了使用final修饰以外,还可以将类的所有构造器变成私有的或者包级私有,并添加公有的静态工厂。

复合优先于继承

要么为继承而设计,并提供文档说明,要么就禁止继承

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值