《Effective Java》阅读笔记 14在公有类中使用访问方法而非公有域

274 阅读3分钟

1.问题

class Point {
    public double x;
    public double y;}
}

如果直接将类中的域暴露为共有域,那么你将失去这个域的控制权。如果你以后想要在类中记录x被赋值了多少次和被获取了多少次,你将无法做到,因为你根本不知道它什么时候在外部被获取,什么时候再外部被赋值。

2.解决办法

class Point {
    private double x;
    private double y;
    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
    public double getX() { return x; }
    public double getY() { return y; }
    public void setX(double x) { this.x = x; }
    public void setY(double y) { this.y = y; }
}

3.特别注意

一个类要确保对所有域的绝对控制权,我们不应该让任何外部类获取到该类的可变对象的引用。 比如说下面这个类,里面有一个域是一个可变对象,我们应该这样做:

public class MyObject{
  private List<String> list = new ArrayList<>;
  public List<String> getList() {
    return new ArrayList(list);
  }
  public void setList(List<String> list) {
    this.list = new ArrayList(list);
  }
}

这样做,外部将永远也获取不到list的引用。

4.总结

  • 公有类永远都不应该暴露在可变的域。坚持面向对象程序设计思想的看法是正确的:如果类可以在它所在的包的外部进行访问,就提供访问方法,以保留将来改变该类的内部表示法的灵活性。如果类暴露了它的数据域,要想将来改变其内部表示法是不可能的,因为公有类的客户端代码已经遍布各处了。

  • 有时候会需要包级私有的或者私有的嵌套类来暴露域==,无论这个类是可变的还是不可变的。虽然客户端代码与该类的内部表示法紧密相连,但是这些代码被限定在包含该类的包中,如果有必要,不改变包之外的任何代码而只改变内部数据表示法也是可以的。在私有嵌套类的情况下,改变的作用范围被进一步限制在外围类中。

  • 让公有类直接暴露域从来不是种好的办法,但是如果域是不可改变的,这种做法的危害就比较小一些。如果不改变类的API,就无法改变这种类的表示法,当域被读取的时候,你也无法采取任何辅助的行为,但是可以强加约束条件,例如,这种类确保了每个实例都表示一个有效的时间:

public final class Time {
    private static final int HOUR_PER_DAY = 24;
    private static final int MINUTES_PER_HOUR = 60;

    public final int hour;
    public final int minute;

    public Time(int hour, int minute) {
        if(hour < 0 || hour >= HOUR_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;
    }
}

5.参考文献

my.oschina.net/jtzen9/blog…

关注公众号“程序员面试之道”

回复“面试”获取面试一整套大礼包!!!

本公众号分享自己从程序员小白到经历春招秋招斩获10几个offer的面试笔试经验,其中包括【Java】、【操作系统】、【计算机网络】、【设计模式】、【数据结构与算法】、【大厂面经】、【数据库】期待你加入!!!

1.计算机网络----三次握手四次挥手

2.梦想成真-----项目自我介绍

3.你们要的设计模式来了

4.震惊!来看《这份程序员面试手册》!!!

5.一字一句教你面试“个人简介”

6.接近30场面试分享