Effective Java 中文版2 (78条军规)
文章平均质量分 55
partner4java
这个作者很懒,什么都没留下…
展开
-
第4条:通过私有构造器强化不可实例化的能力
你可能需要编写只包含静态方法和静态域的类。这样的工具类不希望被实例化,实例化对他没有任何意义。(企图通过将类做成抽象类来强制该类不可被实例化,这是行不通的)demo:// Noninstantiable utility class public class UtilityClass { // Suppress default co原创 2011-12-10 15:43:29 · 705 阅读 · 0 评论 -
第18条:接口优于抽象类
Java语言设计提供了两种机制,可以用来定义允许多个实现的类型:接口和抽象类。因为Java只允许单继承,所以抽象类作为类型定义受到了极大的限制。现有的类可以很容易被更新,以实现新的接口。一般来说,无法更新现有的类来扩展新的抽象类。如果你希望两个类来扩展一个抽象类,就必须把抽象类放到类型层次的高处,以便这两个类的一个祖先成为他的子类。这样会间接的伤害到类的层次,迫使这个公共祖先的原创 2012-03-25 21:38:44 · 1169 阅读 · 1 评论 -
第19条:接口只用于定义类型
当类实现接口时,接口就充当可以引用这个类的实例的类型(type)。因此类实现了接口,就表明客户端可以对这个类的实例实施某些动作。为了其他目的而使用接口是不恰当的。常量接口(constant interface),使用这些常量的类实现这个接口,以避免用类名来修改常量名。常量接口模式是对接口的不良使用。如果这些常量最好被看作枚举类型的成员,使用枚举类型。否则,应该使用不可实例化原创 2012-03-25 22:00:09 · 1239 阅读 · 0 评论 -
第21条:用函数对象表示策略
函数对象:调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象。有些语言支持函数指针(function pointer)、代理(delegate)、lambda表达式(lambda expression),或者支持类似的机制,允许程序把“调用特殊函数的能力”存储起来并传递这种能力。Java没有提供函数指针,但是可以用对象引用实现原创 2012-03-28 22:17:24 · 3282 阅读 · 0 评论 -
第22条:优先考虑静态成员类
嵌套类(nested class)是指被定义在另一个类的内部的类。嵌套类存在的目的应该只是为他的外围类(enclosing class)提供服务。如果嵌套类将来可能会用于其他的某个环境中,他就应该是顶层类(top-level class)。嵌套类有四种:静态成员类(static member class)、非静态成员类(nonstatic member class)、匿名类(anonymo原创 2012-04-03 17:34:39 · 1542 阅读 · 0 评论 -
第16条:复合优先于继承
这里的继承是实现继承而非接口继承。与方法调用不同的是,继承打破了封装性:换句话说,子类依赖于其超类中特定功能的实现细节。超类的实现有可能会随着发型版本的不同而发生改变,如果真的发生了变化,子类可能会遭到破坏,即使他的代码完全没有改变。因此,子类必须跟着超类的更新而改变,除非超类是专门为扩展而设计的,并用具有很好的文档说明。只有当子类真正是超类的子类型(subtype)时,才适合用继承,原创 2012-03-21 21:36:16 · 1162 阅读 · 0 评论 -
第17条:要么为继承设计,并提供文档说明,要么就禁止继承
首先,该类的文档必须精确地描述覆盖每个方法所带来的影响。换句话说,该类必须有文档说明他可覆盖(overridable)的方法的自用型(self-use)。对于每个共有的或受保护的方法或构造器,他的文档必须指明该方法或者构造器调用了哪些可覆盖的方法,是以什么顺序调用的,每个调用的结果又是如何影响后续的处理过程的。更一般的,类必须在文档中说明,在哪些情况下会调用可覆盖的方法。(例如:后台的线程或者原创 2012-03-21 22:45:30 · 976 阅读 · 0 评论 -
第24条:消除非受检警告
许多编译器警告:非受检强制转化警告(unchecked cast warnings)、非受检方法调用警告、非受检普通数组创建警告,以及非受检转换警告(unchecked conversion warnings)。要尽可能地消除每一个非受检警告。如果无法消除警告,同时可以证明引起警告的代码是类型安全的,(只有这种情况下才)可以用一个@SuppressWarnings("unchecked")原创 2012-04-14 23:09:46 · 1399 阅读 · 0 评论 -
第23条:请不要在新代码中使用原生态类型
请不要在新代码中使用原生态类型:声明中具有一个或者多个类型参数(type parameter)的类或者接口,就是泛型(generic)类或者接口。如果不提供类型参数,使用集合类型和其他类型也仍然是合法的,但是不应该这么做。如果使用原生态类型,就失掉了泛型在安全性和表述性方面的所有优势。如果使用像List这样的原生态类型,就会失掉类型安全性,但是如果使用像List这样的参数化类型,则不会原创 2012-04-14 19:00:41 · 1475 阅读 · 0 评论 -
第25条:列表优先于数组
数组与泛型相比,有两个重要的不同点:首先,数组是协变的(convariant)。相反泛型则是不可变的(invariant)。//这是被允许的Object[] objectArray = new Long[1];objectArray[0] = "hello world";//Throws java.lang.ArrayStoreException//Won't comp原创 2012-04-15 11:10:04 · 1266 阅读 · 0 评论 -
第49条:基本类型优先于装箱基本类型
Java有一个类型系统由两部分组成,包含基本类型(primitive),如int、double和boolean,和引用类型(reference type),如String和List。每个基本类型都有一个对应的引用类型,称为装箱基本类型(boxed primitive)。Java 1.5版本中加入了自动装箱(autoboxing)和自动拆箱(auto-unboxing)。int原创 2012-06-05 23:40:10 · 2131 阅读 · 0 评论 -
第39条:必要时进行保护性拷贝
假设类的客户端会尽其所能来破坏这个类的约束条件,因此你必须保护性的设计程序。demo:import java.util.Date;public final class Period { private final Date start; private final Date end; public Period(Date start,Date end) { if(star原创 2012-05-22 23:26:34 · 3125 阅读 · 3 评论 -
第20条:类层次优于标签类
有时候,可能会遇到带有两个甚至更多风格的实例的类,并包含表示实例风格的标签(tag)域。Demo:// Tagged class - vastly inferior to a class hierarchy!class Figure { enum Shape { RECTANGLE, CIRCLE }; // Tag field - the shape of thi原创 2012-03-26 23:00:59 · 2364 阅读 · 3 评论 -
第1条:考虑用静态工厂方法代替构造器
几大优势: 静态工厂方法与构造器不同的第一大优势在于,他们有名称。 静态工厂方法与构造器不同的第二大优势在于,不必在每次调用他们的时候都创建一个新对象。 静态工厂方法与构造器不同的第三大优势在于,他们可以返回原返回类型的任何子类型的对象。 demo:view plaincopy to clipboardprint?//原创 2011-12-09 18:32:38 · 1784 阅读 · 0 评论 -
第15条:使可变性最小化
不可变的类比可变的类更容易设计、实现和使用。为了使类成为不可变,要遵循下面五条规则:1、不要提供任何会修改对象状态的方法。2、保证类不会被扩展。3、使所有的域都是final的。4、使所有的域都成为私有的。5、确保对于任何可变组件的互斥访问。不可变对象本质上是线程安全的,他们不要求同步。不可变对象可以自由地共享。“不可变对象原创 2012-01-06 15:42:55 · 1067 阅读 · 0 评论 -
第7条:避免使用终结方法
终结方法(finalizer)通常是不可预测的,也是很危险的,一般情况下是不必要的。如果程序依赖于终结方法被执行的时间点,那么这个程序的行为在不同的JVM实现中会大相径庭。Java语言规范不仅不保证终结方法会被及时的执行,而且根本不保证他们会被执行。不应该依赖终结方法来更新重要的持久状态。不要被System.gc和System.runFinaliza原创 2011-12-11 14:53:42 · 2423 阅读 · 0 评论 -
第6条:消除过期的对象引用
下面这段程序存在一个“内存泄漏”。在极端的情况下,会导致磁盘交换(Disk Paging),甚至导致程序失败(OutOfMemoryError)。那么哪里引起的内存泄漏呢?如果一个栈先是增长,然后再收缩,那么从栈中弹出来的对象讲不会被当做垃圾回收,即使使用的栈程序不再引用这些对象。这是因为,栈内部维护着对这些对象的过期引用(obsolete reference)。过期引用是指,永远也不原创 2011-12-11 12:17:12 · 1003 阅读 · 0 评论 -
第3条:用私有构造器或者枚举类型强化Singleton属性
在1.5版本之前可以两种实现Singleton的方法,但是都要把构造器保存为私有的。1、公有静态成员是个final域// Singleton with public final field - Page 17 public class Elvis { public static final Elvis INSTANCE = n原创 2011-12-10 11:36:41 · 1349 阅读 · 0 评论 -
第2条:遇到多个构造器参数时要考虑用构建器
重叠构造器模式可行,但是当有许多参数的时候,客户端代码会难以编写,并且仍然较难以阅读。--他的前提是,有很多种不同的构造器情况,也就是很多构造器参数不同,或者说(很多参数可选,因为很多参数有默认值)。 错误示例:view plaincopy to clipboardprint?// Telescoping constructor pattern -原创 2011-12-09 18:57:10 · 896 阅读 · 0 评论 -
第5条:避免创建不必要的对象
一般来说,最好能重用对象而不是在每次需要的时候就创建一个相同功能的新对象。demo1:String s = new String("hello world");需要改成String s = "hello world";因为第一种写法,每一次调用的时候都会创建一个新的String实例。但是第二种写法,在同一台虚拟机中运行的代码,只要他们包含相同的字符串字面常量,就会被重用原创 2011-12-10 17:32:40 · 1287 阅读 · 0 评论 -
第10条:始终要覆盖toString
提供好的toString实现可以使类用起来更加舒适。 在实际应用中,toString方法应该返回对象中包含的所有值的关注的信息。 在实现toString的时候,必须要做出一个很重要的决定:是否在文档中指定返回值的格式。 无论你是否决定指定格式,都应该在文档中明确的表明你的意图。 如果你要指定格式,则应该严格的这样去做。 无论是否指定格式,都为toString返回原创 2011-12-13 20:30:21 · 1003 阅读 · 0 评论 -
第9条:覆盖equals时总要覆盖hashCode
每个覆盖了equals方法的类中,也必须覆盖hashCode方法。 如果不这样的话,就会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常运作,这样的集合包括HashMap、HashSet和Hashtable。在引用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须原创 2011-12-13 18:26:19 · 3187 阅读 · 1 评论 -
第11条:谨慎的覆盖clone
Cloneable接口的目的是作为对象的一个mixin接口(mixin interface),表明这样的对象允许克隆(clone)。 遗憾的是,他并没有成功的达到这个目的。其主要的缺陷在于,他缺少一个clone方法,Object的clone方法是受保护的。 如果不借助于反射(reflection),就不能仅仅因为一个对戏那个实现了Cloneable,就可以调用clone。 de原创 2011-12-14 17:06:42 · 1604 阅读 · 0 评论 -
第8条:覆盖equals时请遵守通用约定
需要满足的条件: 类的每个实例本质上都是唯一的。 不关心类是否提供了“逻辑相等(logical equality)”的测试功能。 超类已经覆盖了equals,从超类继承过来的行为对于子类也是合适的。 类是私有的或是包级私有的,可以确定他的equals方法永远不会被调用。 需要覆盖equals:如果类具有自己特有的“逻辑相等”概念,而且超类还没有覆盖equals以实现期望原创 2011-12-13 12:08:41 · 1751 阅读 · 0 评论 -
第13条:使类和成员的可访问性最小化
概念:要区别设计良好的模块与设计不好的模块,最重要的因素在于,这个模块对于外部的其他模块而言,是否隐藏其内部数据和其他细节。设计良好的模块会隐藏所有的实现细节,把他的API和他的实现清晰的分割开来。然后,模块之间通过他们之间的API进行通信,一个模块不需要知道其他模块的内部情况。这个概念被成为信息隐藏(information hiding)或封装(encapsulation),是软件设原创 2012-01-06 11:40:43 · 1205 阅读 · 0 评论 -
第14条:在公有类中使用访问方法而非公有域
如果类可以在他所在的包的外部进行访问,就提供访问方法。如果类是包私有的,或者私有的嵌套类,直接暴露他的数据域并没有本质的错误。总之,公有类永远都不应该暴漏可变的域。虽然还是有几个问题,但是让公有类暴漏不可变的域,起危害比较小。但是,有时候需要会用到包级私有的或者私有的嵌套类来暴漏域,无论这个类是可变还是不可变。Demo:package cn.part原创 2012-01-06 12:22:18 · 1456 阅读 · 0 评论 -
第38条:检查参数的有效性
每当编写方法或者构造器的时候,应该考虑他的参数有哪些限制。应该把这些限制写到文档中,并且在这个方法体的开头处,通过显式的检查来实施这些限制。养成这样的习惯是非常重要的。demo:1\对于公有的方法,要用Javadoc的@throws标签(tag)在文档中说明违反参数值限制会抛出异常。手工抛出异常,并且添加@throws注解说明原因 /** * hello.....原创 2012-05-22 22:02:15 · 2523 阅读 · 0 评论