第八章 讨论方法(还需要整理)

方法设计的几个方面,如何处理参数和返回值,如何设计方法签名,如何编写方法文档

第四十九条 ,检查参数的有效性
1.没有验证的参数的有效性,可能导致违背失败的原子性
2.对于公有的和受保护的放啊,要用javadoc的@throws标签在文档中说明违反参数数值限制时会抛出的异常
3.在java7中增加的Objects.requireNonNull方法比较灵活且方便,因此不必再手工进行null检查
4.java9添加了范围检查,checkFromIndexSize,checkFromToIndex,checkIndex
5.非公有的方法通常应该使用断言来检查他们的参数 assert 断言,Java在执行的时候默认是不启动断言检查的
(这个时候,所有的断言语句都将忽略!),如果要开启断言检查,则需要用开关-enableassertions或-ea来开启。

第五十条,必要时进行保护性拷贝
1.假设类的客户端会尽所能来破坏这个类的约束条件,因此你必须保护性地设计程序
2.Date已经过期了,不应该在新代码中使用,可以使用Instant LocalDateTime ZoneDateTime
3.对于构造器的每个可变的参数进行保护性拷贝是必须的
4.保护性拷贝是在检查参数的有效性之前进行的,并且有效性检查是针对拷贝之后的对象,而不是针对原始对象,
防止在检查参数时,另一个线程改变参数的状态,这一段时间被称为time-of-check/time-of-use或者TOCTOU攻击
5.对于参数类型可以被不可信任方子类化的参数,请不要使用clone方法进行保护性拷贝,子类可以在每个实例被
创建的时候,把指向该实例的引用记录到一个私有的静态列表中,并允许攻击者访问这个列表,这将使得攻击者
可以自由地控制所有实例
6.返回内部状态的一个拷贝

第五十一条,谨慎设计方法签名
1.谨慎地选择方法名称
2.不要过于追求提供便利的方法,当一项操作被经常用到,才考虑为它提供便利的方法
3.避免过长的参数列表,目标4个或者更少,特别是相同类型的长参数格外有害,容易传错
1.把一个方法分解成多个方法,每个方法只需要这些参数的一个子集
2.创建辅助类,用来保存参数分组,这些辅助类一般为静态成员
3.从对像创建和方法的调用都采用builder模式
4.对于参数类型,要优先使用接口而不是类
5.对于boolean参数,要优先使用两个元素的枚举类型

第五十二条,慎用重载
1.方法重载,当两个方法的参数是父子类,那么要调用哪个重载方法是在编译时做出决定的
2.对于重载方法的选择是静态的,而对于被覆盖的方法选择则是动态的
3.应该避免胡乱地使用重载机制
1.安全保守的策略是,永远不要导出两个具有相同参数数目的重载方法,可以起不同的名字,而不是使用重载
2.构造器不可以命名的方法重载,可以使用静态工厂
3.至少有一个参数对于的类型在两个参数数目相同的重载方法里是根本不同的
4.ArrayList().remove(Object) 和 ArrayList().remove(index) 可能在遍历时,删除的是下标,而不是元素
5.不要在相同的参数位置调用带有不同函数接口的方法
6.让更具体化的重载方法把调用转发给更一般化的重载反方

第五十三条,慎用可变参数
1.可变参数的机制是首先创建一个数组,数组的大小为调用位置所传递的参数数量,然后把参数传到数组,最后
把数组传给方法
2.min(int a,int...array);
3.min(int a);min(int a,int b);min(int a,int b,int c);min(int a,int b,int c,,int d) 性能优化(变参数的机制是首先创建一个数组)

第五十四条,返回零长度的数组或者集合,而不是null
1.Collections.emptySet,Collections.emptyMap返回一个0长度的列表
2.永远不要返回null,而不返回一个零长度的数组或者集合

第五十五条,谨慎返回optional(不能返回值)
1.抛出异常开销高,返回null可能导致客户端需要判断null,optional是一个不可变的容易
2.永远不要通过返回optional的方法返回null
3.optional本质上与受检异常相类似,可以提供一个默认值,max(words).orElse("No words"),也可以抛出异常
Optional.of("dsada").orElseThrow(RuntimeException::new);
4.isPresent()返回是否是空值
5.容器类型包括集合,映射,数组和optional,都不应该被包装在optional中
6.如果无法返回结果并且没有返回结果的客户端必须执行特殊处理,那么就应该声明该方法返回optional,读取
optional需要额外的花费,不适合用于注重性能的情况
7.永远不应该返回基本包装类型的optional,小型的基本类型,boolean,byte,character,short,float除外
8.几乎永远都不适合用optional作为键,值,或者集合或者数组的元素

第五十六,为所有导出的Api元素编写文档注释
1.为了正确的编写api文档,必须在每个被导出的类,接口,构造器,方法和域声明之前添加一个文档注释
2.方法的文档注释应该简洁的描述出它和客户端之间的约定,做了什么,而不是怎么做,前置条件和后置条件,
副作用,
3.文档注释在源代码和产生的文档中都应该是易于阅读的
4.同一个类或者接口中的两个成员或者构造器,不应该具有同样的概要描述
5.概要描述是文档注释中第一个句子
6.当为了泛型或者方法编写文档时,确保要在文档中说明所有的类型参数
7.当为了枚举类型编写文档时,要确保在文档中说明常量
8.为注解类型编写文档时,要确保在文档中说明所有成员,以及类型本身
9.类或者静态方法是否线程安全,应该在文档中对它的线程级别进行说明

你可能感兴趣的:(第八章 讨论方法(还需要整理))