《Effective Java 2nd》第7章 方法

目录

第38条 检查参数的有效性

第39条 必要时进行保护性拷贝

第40条 谨慎设计方法签名

第41条 慎用重载

第42条 慎用可变参数

第43条 返回零长度的数组或集合,而不是null

第44条 为所有导出的API元素编写文档注释

关注点:可用性、健壮性、灵活性

第38条 检查参数的有效性

在编写方法或者构造器的时候,应该考虑参数有哪些限制,并显式检查

第39条 必要时进行保护性拷贝

如果类具有从客户端得到或者返回到客户端的可变组件,为了维持不可变性,必要时进行保护性拷贝。

否则,在文档中写明,不可修改此组件。

举例:

public final class Period {
   private final Date start;
   private final Date end;
   public Period(Date start, Date end) {
      if (start.compareTo(end) > 0) {
         throw new IllegalArgumentException(strat + "after" + end);
      }
      this.start = start;
      this.end = end;
   }
   public Date start() {
      return start;
   }
   public Date end() {
      return end;
   }
}

Period表示一段不可变的时间周期。

但是,Period并不是不可变的!!!因为Date是可变的。

Date start = new Date();
Date end = new Date();
Period p = new Period(strat, end);
end.setYear(78);//因为Date是可变的,导致p被修改了

解决方法:

public Period(Date start, Date end) {
      //先进行保护性拷贝,然后再对拷贝后的进行检查
      this.start = new Date(start.getTime()); //使用保护性拷贝
      this.end = new Date(end.getTime()); //使用保护性拷贝
      if (this.start.compareTo(this.end) > 0) {
         throw new IllegalArgumentException(strat + "after" + end);
      }
   }

Period仍旧是可以被改变的。

Date start = new Date();
Date end = new Date();
Period p = new Period(strat, end);
p.end().setYear(78);//因为Date是可变的,导致p被修改了

解决方法:

   public Date start() {
      return new Date(start.getTime());
   }
   public Date end() {
      return new Date(end.getTime());
   }

第40条 谨慎设计方法签名

1.避免过长的参数列表。4个参数,或者更少。

不要定义相同类型的长参数序列,容易不小心弄错了参数顺序。

如何缩短过长参数列表?

1)拆分成多个方法

2)创建辅助类,保存参数的分组。

3)采用Builder模式。在方法带有多个参数,且有些是可选参数的时候,这个方法尤其有用!

2.对于参数类型,优先使用接口而不是类。

3.对于boolean类型,优先使用两个元素的枚举类型

第41条 慎用重载

为何慎用重载?

因为在特殊情形(类型转换、自动装箱拆箱等)下,很难确定到底哪个重载方法会被调用。

建议

1) 对于多个有相同参数数目的方法来说,应尽量避免重载。

2)要避免这种情况:同一组参数只需经过类型转换就能传递给不同的重载方法。

举例:m(List<?> s),m(Set<?> s),m(Collection<?> s)。

第42条 慎用可变参数

在重视性能情况下,使用可变参数要小心。可变参数的每次调用都会导致一次数组分配和初始化。

如何改进?当确定95%的调用有3个或更少的参数时,定义5个重载方法。

m()

m(int a)

m(int a, int b)

m(int a, int b, int c)

m(int a, int b, int c, int ....rest)

第43条 返回零长度的数组或集合,而不是null

对于返回类型为数组或集合的方法返回一个零长度的数组或者集合,而不是返回null。

第44条 为所有导出的API元素编写文档注释

原文地址:https://www.cnblogs.com/yeyang/p/10489079.html

时间: 2024-10-01 00:52:02

《Effective Java 2nd》第7章 方法的相关文章

[Effective Java]第七章 方法

第七章      方法 38.      检查参数的有效性 绝大多数方法和构造器对于传递给它们的参数值都会有某些限制.例如,索引值必须是非负的,对象引用不能为null等,这些都是常见的.你应该在文档中清楚地指明所有这些限制,并且在方法体的开头处检查参数,以强制施加这些限制. 应该在方法和构造器体前进行了参数的有效性检查,并且及时向外抛出适当的异常.如果方法没有检查它的参数,就有可能发生几种情形.该方法可能在处理过程中失败,并且产生令人费解的异常,更有可能,该方法可以正常返回,但是会悄悄地计算出错

Effective java 第三章对于所有对象都通用的方法(一) 读书笔记

对于所有对象都通用的方法 覆盖equals时请遵守通用约定 类的每个实例本质上都是唯一的. 不关心类是否提供了逻辑相等的测试功能 超类已经覆盖了equals,从超类继承过来的行为对于子类也是合适的. 类是私有的或是包级私有的,可以确定它的equals方法永远不会被调用. throw new AssertionError() 一般覆盖Object.equals都是值类 但有一种值类不需要覆盖equals方法,即实例受控,确保每个值至多只存在一个对象的类.如枚举 覆盖equals方法,通用约定. 自

[Effective Java]第六章 枚举和注解

第六章      枚举和注解 30.      用enum代替int常量 枚举类型是指由一组固定的常量组成合法值的类型,例如一年中的季节或一副牌中的花色.在没引入枚举时,一般是声明一组int常量,每个类型成员一个常量: public static final int APPLE_FUJI = 0; public static final int APPLE_PIPPIN = 1; public static final int APPLE_GRANNY_SMITH = 2; public sta

[读书笔记]Effective Java 第四章

使类和成员的可访问性最小化 规则很简单:尽可能地使每个类或者成员不被外界访问.实例域(非final)决不能是公有的.当需要暴露出不可变的实例时通常会把这个实例做成不可变或者是把这个实例变成私有,同时提供该实例的备份. 在公有类中使用访问方法而非公有域 这就是常说的getter和setter方法,提供给包外访问时提供必要的方法,限制客户端的行为,以便于将来可以在内部改变表示方法. 使可变性最小化 不可变的类比可变类更加易于设计.实现和使用.它们不容易出错,且更加安全.为了使类成为不可变,要遵循下面

Effective java经验之谈,通用方法

对于通用方法,其实应用的场景是比较多的,我们在写一个类的时候,就要考虑是否要编写该方法的通用方法.这使得我们为以后该类的扩展性与使用方面提供很大的便利. 1.      覆盖equals时请遵守通用约定.自反性,对称性,传递性,一致性,非空性.编写子类equals的方法的时候,可以考虑是否可以用复合,不使用继承来解决问题.Instanceof进行参数检测,如果参数null,也将返回false. 2.      覆盖equals时总要覆盖hashCode. 1.对象属性不变化,返回的hashcod

Effective Java 读书笔记之六 方法

一.检查参数的有效性 1.考虑参数有哪些限制,把限制写到文档中,在方法的开头处通过显式地检查来实施这些限制. 二.必要时进行保护性拷贝 1.如果类具有从客户端得到或者返回的可变组件,类就必须考虑保护性拷贝这些组件. 2.如果拷贝成本比较高,类又可以信任他的客户端,不进行拷贝保护,但要进行文档的说明. 三.谨慎设计方法签名 1.谨慎地选择方法的名称:遵守规范,保持风格一致. 2.不要过于追求提供便利的方法. 3.编码过长的参数列表 a.一个方法分解成多个方法 b.创建辅助类,保存参数的分组. c.

[读书笔记]Effective Java 第三章

覆盖equals方法时请遵守通用约定 这种说法的大意是要说明,Object类中定义的很多默认准则是被许多工具类或是第三方框架共同遵守的标准,一旦改动这样的标准机制,会在后续的使用中产生不稳定因素.equals方法常见用来做以下用途时,不建议对equals方法进行覆盖: 1.判断实例的唯一性 2.提供某种程度的逻辑相等 equals方法满足自反性,对称性,传递性,一致性,非空性.当需要覆盖equals方法时,需要注意以下三点: 1.覆盖equals时总要覆盖hashCode 2.不要企图让equa

java 第五章 方法定义及调用

1.方法的定义 什么是方法 方法是完成某个功能的一组语句,通常将常用的功能写成一个方法 方法的定义 [访问控制符] [修饰符] 返回值类型 方法名( (参数类型 形式参数, ,参数类型 形式参数, ,-) ) { 方法体 } 修饰符:public .static 被称为修饰符(后续会详细讲解它们): 返回值类型:用来说明该方法运算结果的类型.如果返回其他类型,编译就可能出错: 方法名:它作为调用时引用方法的标识: 参数列表:方法的参数个数可以是0个到多个,每个参数前面要声明参数的数据类型:每个参

Effective Java 读书笔记(一):使用静态工厂方法代替构造器

这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文<java中final与static的使用场景总结>. 什么是静态工厂方法? 可以参考书中的例子(摘自JDK1.7 java.lang.Boolean) public final class Boolean implements java.io.Serializable, Comparable<

effective java —— 终结方法守卫者

目录: effective java —— 终结方法守卫者 effective java 第2章:创建和销毁对象.第7条 : 避免使用终结方法.最后的“终结方法守卫者 (finalizer guardian)”的例子,以加深理解. 1 /** 2 * chapter 2——终结守卫者 3 * @ClassName: Parent 4 * TODO 5 * @author xingle 6 * @date 2015-3-11 下午3:49:47 7 */ 8 public class Parent