Tips

《Effective Java, Third Edition》一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化。

在这里第一时间翻译成中文版。供大家学习分享之用。

16. 在公共类中使用访问方法而不是公共属性

有时候,你可能会试图写一些退化的类(degenerate classes),除了集中实例属性之外别无用处:

// Degenerate classes like this should not be public!
class Point {
public double x;
public double y;
}

由于这些类的数据属性可以直接被访问,因此这些类不提供封装的好处(条目 15)。 如果不更改API,则无法更改其表示形式,无法强制执行不变量,并且在访问属性时无法执行辅助操作。 坚持面向对象的程序员觉得这样的类是厌恶的,应该被具有私有属性和公共访问方法的类(getter)所取代,而对于可变类来说,它们应该被替换为setter设值方法:

// Encapsulation of data by accessor methods and mutators
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; } }

当然,对于公共类来说,坚持面向对象是正确的:如果一个类在其包之外是可访问的,则提供访问方法来保留更改类内部表示的灵活性。如果一个公共类暴露其数据属性,那么以后更改其表示形式基本上没有可能,因为客户端代码可以散布在很多地方。

但是,如果一个类是包级私有的,或者是一个私有的内部类,那么暴露它的数据属性就没有什么本质上的错误——假设它们提供足够描述该类提供的抽象。在类定义和使用它的客户端代码中,这种方法比访问方法产生更少的视觉混乱。 虽然客户端代码绑定到类的内部表示,但是这些代码仅限于包含该类的包。 如果类的内部表示是可取的,可以在不触碰包外的任何代码的情况下进行更改。 在私有内部类的情况下,更改作用范围进一步限制在封闭类中。

Java平台类库中的几个类违反了公共类不应直接暴露属性的建议。 着名的例子包括java.awt包中的PointDimension类。 这些类别应该被视为警示性的示例,而不是模仿的例子。 如条目 67所述,暴露Dimension的内部结构的决定是一个严重的性能问题,这个问题在今天仍然存在。

虽然公共类直接暴露属性并不是一个好主意,但是如果属性是不可变的,那么危害就不那么大了。当一个属性是只读的时候,除了更改类的API外,你不能改变类的内部表示形式,也不能采取一些辅助的行为,但是可以加强不变性。例如,下面的例子中保证每个实例表示一个有效的时间:

// 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 minute; 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
}

总之,公共类不应该暴露可变属性。 公共累暴露不可变属性的危害虽然仍然存在问题,但其危害较小。 然而,有时需要包级私有或私有内部类来暴露属性,无论此类是否是可变的。

Effective Java 第三版——16.在公共类中使用访问方法而不是公共属性的更多相关文章

  1. Effective Java 第三版——23. 优先使用类层次而不是标签类

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  2. Effective Java 第三版——46. 优先考虑流中无副作用的函数

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  3. Effective Java 第三版——75. 在详细信息中包含失败捕获信息

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  4. 《Effective Java 第三版》目录汇总

    经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...

  5. 《Effective Java 第三版》新条目介绍

    版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...

  6. Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. Effective Java 第三版——10. 重写equals方法时遵守通用约定

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. Effective Java 第三版——15. 使类和成员的可访问性最小化

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  9. Effective Java 第三版——18. 组合优于继承

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

随机推荐

  1. lnmp1.3 配置pathinfo---thinkphp3.2 亲测有效

    lnmp1.3环境下配置pathinfo模式试了很多方法,都以失败告终,博主被这个问题困扰了很久,终于解决了!现记录如下: 1.打开php.ini 通常该文件在 /usr/local/php/etc/ ...

  2. indexOf 和 lastIndexOf的区别

    indexOf 和  lastIndexOf 是什么? indexOf 和 lastIndexOf 都是索引文件 indexOf 是查某个指定的字符串在字符串首次出现的位置(索引值) (也就是从前往后 ...

  3. Android破解学习之路(三)——Android游戏 切水果破解

    经过前两篇破解教程,想必大家也是明白了破解的简单流程了. 先对APP进行试用,了解APP运行的大概流程,之后从APP中找出关键字(一般的关键字差不多都是支付失败),之后使用Androidkiller进 ...

  4. Android Weekly Notes Issue #287

    Android Weekly Issue #287 December 10th, 2017 Android Weekly Issue #287 圣诞节快要来了,小编也偷懒了,本期内容包括如何通过AS添 ...

  5. 翻煎饼 Stacks of Flapjacks

    题意:本题意为煎饼排序,大的放在上面,小的放在下面(此题输入是从上到下输入的),为煎饼排序是通过一系列的"翻转"动作来完成的.翻转动作就是将一个小铲插到一叠煎饼中的某两个煎饼之间, ...

  6. python入门基础

    Python 入门 变量 什么是变量?变量就是变化的量,核心是"变"和"量"两个字,变就是变化,量就是衡量状态. 为什么需要变量?程序执行的本质就是一系列状态的 ...

  7. 从durable谈起,我是如何用搜索引擎抓住技术的关键字学习新姿势打开敏捷开发的大门

    ---又名我讨厌伸手党 我又把个人博客的子标题改为了 你可以在书和搜索引擎找到90%的问题的答案,为什么要问别人?剩下的10%或许没有答案,为什么要问别人? 这是由于最近在网上看到各种伸手,对于我这种 ...

  8. 转自知乎-wifi破解

    上点python有意思的代码. 环境准备 python2.7 pywifi模块 字典 清除系统中的任何wifi连接记录 导入模块 这里用的模块就这三个 pywifi的_wifiutil_linux.p ...

  9. 怎样使用Android Studio开发Gradle插件

    缘由 首先说明一下为什么会有这篇文章.前段时间,插件化以及热修复的技术非常热,Nuwa热修复的工具NuwaGradle,携程动态载入技术DynamicAPK,还有希望做最轻巧的插件化框架的Small. ...

  10. js----数组处理之splice(有js原始addClass方法哦)

    上次写了一个轮播的方法:http://blog.csdn.net/stronglyh/article/details/46833499 由于别人问我的时候,给了我html.于是乎我就看到了页面中引用了 ...