Effective Java:Ch4_Class:Item14_在public类中应该使用访问方法而不是public域
你可能偶尔需要编写退化类,目的只是为了集中实例域:
// Degenerate classes like this should not be public!
class Point {
public double x;
public double y;
}
由于这种类的数据域是可以直接访问的,所以他们不能提供“封装”带来的好处。如果不改变API,就不能改变其数据表示法,不能强加任何约束,当域被访问时不能采取任何辅助行为。强硬派的面向对象程序员会非常厌恶这种类,认为这种类应该被包含private域和public访问方法(getter)的类替代。对于可变类,还应该包含setter。
// Encapsulation of data by accessor 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; }
}
毫无疑问,强硬派的观点在public类上是正确的:如果一个类可以被包外访问,那么就要提供访问方法,以便可以灵活地改变类的内部表示。如果public类暴露了其数据域,则要想在将来改变内部表示是不可能的,因为他的客户端代码可能已经遍布各处了。
然而,如果类是package-private或是private嵌套类,那么把数据域暴露出去并没有本质的错误——假设这些数据域充分描述了该类提供的抽象。无论是在类定义中,还是在客户端代码中,这种方法相对于访问方法更不会产生视觉混乱。虽然客户端代码与类的内部表示紧密相连,但这些代码被限定在同一个包中。如果需要改变内部数据表示,你不必修改包外的任何代码。如果是private嵌套类,则甚至不需要修改类外的任何代码。
JDK中的几个类违反了“public类不应该直接暴漏其字段”这个告诫。最显著的例子是java.awt包中的Point类和Dimension类。正如Item55中讲的,决定暴露Dimentsion类的内部实现造成了严重的性能问题,而且这个问题至今还存在。
——Component.getSize()返回Dimension,每次调用都要new一个新的对象。
虽然直接暴露public类的字段永远都不是个好主意,但是如果该域是不可变的(immutable),则危害性就小得多。除非修改其API,否则你不能修改其内部数据表示,而且当别人读取该字段时 你不能采取任何附加行动,但是你可以强加约束条件(——因为只有你自己可以set该字段)。例如,下面这个类保证了每个实例都表示一个合法的时间。
// public class with exposed immutable fields - questionable
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() {
//强加约束条件
if (hour < 0 || hour >= HOUR_PER_DAY) {
throw new IllegalArgumentException();
if (minute < 0 || minute >= MINUTES_PER_HOUR) {
throw new IllegalArgumentException(); this.hour = hour;
this.minute = minute;
} }
总之,public类永远不要暴露其可变的字段。而public类暴露其不可变字段随然是有问题,但危害性要小一些。然而,package-private或者private的嵌套类暴露其字段则是可行的,无论该字段是可变还是非可变。
Effective Java:Ch4_Class:Item14_在public类中应该使用访问方法而不是public域的更多相关文章
- Effective Java 第三版——16.在公共类中使用访问方法而不是公共属性
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- [Effective Java]第三章 对所有对象都通用的方法
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- org.apache.commons.lang3.StringUtils类中isBlank和isEmpty方法的区别
相信很多java程序员在写代码的时候遇到判断某字符串是否为空的时候会用到StringUtils类中isBlank和isEmpty方法,这两个方法到底有什么区别呢?我们用一段代码来阐述这个区别吧: @T ...
- 在eclispe的类中快速打出main方法
在java类中快速打出main方法有两种途径: 1. 在新建类时,在New Java Class窗口中,将public static void main ( String[ ] args ) 前面打上 ...
- 菜鸡的Java笔记 第十三 String 类的两种实例化方法
String 类的两种实例化方法 String 类的两种实例化方式的区别 String 类对象的比较 Stirng 类对象的使用分析 /* 1.String 类的两种实例化方式的区别 ...
- 创建如下三个类:(People类中的三个方法分别输出一些信息,ChinaPeople 和AmericanPeople类重写父类的三个方法)。
创建如下三个类:(People类中的三个方法分别输出一些信息,ChinaPeople 和AmericanPeople类重写父类的三个方法). ackage com.chuoji.text01; pub ...
- UnSafe类中的一些重要方法
UnSafe类中的一些重要方法 JDK中的rt.jar保重Unsafe类中提供了硬件级别的原子性操作,Unsafe类中的方法都是navtice方法,他们使用JNI的方式访问C++实现库,下面我们来了解 ...
- php面向对象类中常用的魔术方法
php面向对象类中常用的魔术方法 1.__construct():构造方法,当类被实例化new $class时被自动调用的方法,在类的继承中可以继承与覆盖该方法,例: //__construct( ...
- 关于Integer类中parseInt()和valueOf()方法的区别以及int和String类性的转换.以及String类valueOf()方法
Integer类中的. 关于parseInt()方法的API文档. 返回的是int类型的 关于valueOf()方法的API文档 返回的是Integer类型的. 关于intValue()方法的API ...
随机推荐
- Android - 视图Android应用(apk)签名
视图Android应用(apk)签名 本文地址: http://blog.csdn.net/caroline_wendy 在微博.微信开放平台注冊应用时,须要填写应用(apk)的签名,能够使用keyt ...
- openSUSE 安装
https://lug.ustc.edu.cn/sites/opensuse-guide/installation.php 开始 1. 简介2. 改用 GNU/Linux3. 获取 openSUSE4 ...
- iOS8自适应布局视频教程
联系:http://www.elsyy.com/course/6480 这是颐和园最近录制iOS8视频课程.简介iOS8出现在自适应布局. 本教程的书,颐和园<ios8 swift编程指南> ...
- csu 1503: 点弧之间的距离-湖南省第十届大学生计算机程序设计大赛
这是--比量p并用交点连接中心不上弧.在于:它至p距离.是不是p与端点之间的最短距离 #include<iostream> #include<map> #include< ...
- 开发者:网站 & SDK
{ 收集的一些.开发工具 } Teambition 团队协作工具 GitCafe 代码托管 FIR.im App 托管平台 Coding 代码托管,项目管理,WebIDE 计蒜客 编程学习 SendC ...
- [CLR via C#]5.1 基元类型
原文:[CLR via C#]5.1 基元类型 某些数据类在开发中非常常用,以至于许多编译器允许代码已简化的语法来操作它们.例如可以使用以下语法来分配一个整数: System.Int32 a = ne ...
- Spark Standalone模式应用程序开发
作者:过往记忆 | 新浪微博:左手牵右手TEL | 能够转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明博客地址:http://www.iteblog.com/文章标题:<Spar ...
- [DevEpxress]GridControl 显示Gif动画
原文:[DevEpxress]GridControl 显示Gif动画 如果没有对进行设置,那么GridControl列中gif在编辑状态下,才能显示动画效果,如果要设置列自动显示动画效果,可以进行如下 ...
- javascript 控制台输出 图片 console.log 真强大 真佩服你们的创造力
无意中,在百度知道页面发现了这货.居然能输出图片到控制台. 完全颠覆自己的三观,果断查阅其输出方法.后得知,原来如此. 曾经做过的项目中,同事把控制台做成一个网页形式方便远程控制和远程调用.没想到过这 ...
- 让IE6支持position:fixed的方法,CSS expression与JavaScript eval讲解
做吸顶效果或是固定效果时,使用position:fixed无非是最方便的,可是万恶的IE6是没有fixed这个属性值的,而我们要使IE6能够像fixed一样固定在浏览器中的某个位置,使用onscrol ...