Effective Java读书笔记(三)

来源:互联网 发布:python读取dat文件 编辑:程序博客网 时间:2024/05/21 21:46

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

实例域决不能是公有的。如果域是非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 - questionablepublic 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修饰以外,还可以将类的所有构造器变成私有的或者包级私有,并添加公有的静态工厂。

复合优先于继承

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

0 0
原创粉丝点击