第三十八条:检查参数的有效性

第三十九条:必要时进行保护性拷贝

  public class Period {
private final Date start;
private final Date end; public Period(Date start, Date end) {
this.start = start;
this.end = end;
} public Date start() {
return start;
} public Date end() {
return end;
}
}

写完上面的代码后会认为这是一个很安全的了,不可变,初始化了之后就不可以start和end就不可以改变了,but,真这样?注意Date是可变的

      Date start = new Date();
Date end = new Date();
Period period = new Period(start, end);
end.setTime(System.currentTimeMillis());

这样就把原本的时间改变了。

  public class Period {
private final Date start;
private final Date end; public Period(Date start, Date end) {
this.start = new Date(start.getTime());
this.end = new Date(end.getTime());
} public Date start() {
return new Date(start.getTime());
} public Date end() {
return new Date(end.getTime());
}

程序改成这样后,这个类就真的不可变了,穿件和向客户端返回数据的时候都不是本身的引用,而是另一个实例。这里也没用,如果用clone方法,客户端还可能编写Date的子类,如果在子类里包含攻击代码,如在子类的实例被创建的时候把指向该实例的引用记录到一个私有的静态列表中。

第四十条:谨慎设计方法签名
这个是对设计API的技巧

  • 谨慎的选择方法的名称
  • 不要国语追求提供遍历的方法。意思是不要暴露过多的方法,这样会很难学习、使用、文档化。只要提供这个类应该提供的方法就可以了。
  • 避免过长的参数列表。

三种方法缩短参数

  • 把方法分解多个小方法
  • 创建辅助类
  • 采用建造者模式(Builder)。前面的有例子,就在类内部建造一个Builder类,在这个里设计各种参数,是根据方法设置的参数已读。外部类的构造器将内部Builder的类的参数赋值给外部类。

对于boolean类型,优先采用enum。

第四十一条:慎用重载
看一下下面的例子

  class CollecitonClassifier {
public static String classify(Set<?> s) {
return "Set";
}
public static String classify(List<?> s) {
return "List";
}
public static String classify(Collection<?> s) {
return "Unknown";
}
public static void main(String[] args) {
Collection<?>[] collections ={new HashSet<String>(), new ArrayList<String>(), new HashMap<String, String>().values()};
for (Collection<?> collection : collections)
System.out.println(FourtyFirst.CollecitonClassifier.classify(collection));
}
}

期望的结果是"Set" "List" "Unknown",但是上面的结果是三个Unknown。在看下面的例子

  class Wine{
String name(){return "wine";}
}
class Champagne extends Wine{
@Override
String name(){return "Champagne";}
}
public void test() {
Wine[] wines = {new Wine(), new Champagne()};
for (Wine wine : wines)
System.out.println(wine.name());
}

这样就是所期望的结果"Wine" "Champagne"
为什么第一个的输出和想的不一样,在声明类型的时候声明出来的最终结果就是Collection类型的,因此最终就是进入 public static String classify(Collection<?> s) {}这个方法。而下面方法的覆盖就能根据类型找到具体的方法。
对于重载方法的选择是静态的,而对于覆盖的选择是动态的。对于重载,在编译时就已经确定了类型(Collection)。而对于方法覆盖,是在运行时才知道当前是什么类型,根据类型类确定到底调用哪个类的方法。
还有在用Set和List时要注意,Set有remove(i) 和remove(E)方法,如果你的Set中放的是Integer,注意一下这个地方,很可能想移除的是Set中的元素,而却调用了remove(i)的方法,移除的是索引为i的。List同样要注意。
为了避免重载方法出现的问题,最好不要出现相同参数个数的重载方法,起个其他的名字又不是难事。

第四十二条:慎用可变参数
int sum(int ...arg) {}  可变参数就是这种类型的参数。

第四十三条:返回零长度的数组或者集合,而不是null

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

Effective java -- 6 方法的更多相关文章

  1. effective java —— 终结方法守卫者

    目录: effective java —— 终结方法守卫者 effective java 第2章:创建和销毁对象.第7条 : 避免使用终结方法.最后的“终结方法守卫者 (finalizer guard ...

  2. Effective java笔记(二),所有对象的通用方法

    Object类的所有非final方法(equals.hashCode.toString.clone.finalize)都要遵守通用约定(general contract),否则其它依赖于这些约定的类( ...

  3. Effective Java 学习笔记之第七条——避免使用终结(finalizer)方法

    避免使用终结方法(finalizer) 终结方法(finalizer)通常是不可预测的,也是很危险的,一般情况下是不必要的. 不要把finalizer当成C++中析构函数的对应物.java中,当对象不 ...

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

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

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

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

  6. Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法

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

  7. Effective Java 第三版——12. 始终重写 toString 方法

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

  8. Effective Java 第三版——13. 谨慎地重写 clone 方法

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

  9. Effective Java 第三版——16.在公共类中使用访问方法而不是公共属性

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

随机推荐

  1. 51单片机 | A/D转换器实现数字电压表实例

    ———————————————————————————————————————————— ADC0809 - - - - - - - - - - - - - - - - - - - - - - - - ...

  2. MySQL + Amoeba 负载均衡、主从备份方案

    1.  基本环境 4台内网虚拟机的操作系统都是ubuntu-14.04.4 64位 IP为:192.168.169.11.192.168.169.12.192.168.169.13.192.168.1 ...

  3. 浅析VS2010反汇编 VS 反汇编方法及常用汇编指令介绍 VS2015使用技巧 调试-反汇编 查看C语言代码对应的汇编代码

    浅析VS2010反汇编 2015年07月25日 21:53:11 阅读数:4374 第一篇 1. 如何进行反汇编 在调试的环境下,我们可以很方便地通过反汇编窗口查看程序生成的反汇编信息.如下图所示. ...

  4. 使用itchat分析自己的微信(1)

    1.准备工作 安装itchat pip install itchat参考 itchat内部函数 2.个人微信男女比例分析 ''' Have fun:itchat Author:杨 景 Time:201 ...

  5. Laravel 数据库实例教程 —— 使用DB门面操作数据库

    Laravel支持多种数据库,包括MySQL.Postgres.SQLite和SQL Server,在Laravel中连接数据库和查询数据库都非常简单,我们可以使用多种方式与数据库进行交互,包括原生S ...

  6. Apollo配置中心解惑(一):关于一个portal管理多个环境,要求环境相互之间不影响,独立

    关于作者的回答很官方,不太懂: https://github.com/ctripcorp/apollo/wiki/%E5%88%86%E5%B8%83%E5%BC%8F%E9%83%A8%E7%BD% ...

  7. 【Caffe代码解析】Blob

    主要功能: Blob 是Caffe作为传输数据的媒介,不管是网络权重參数,还是输入数据,都是转化为Blob数据结构来存储,网络,求解器等都是直接与此结构打交道的. 其直观的能够把它看成一个有4纬的结构 ...

  8. nginx反向代理带路径访问问题

    nginx的配置为192.168.0.219:80分别映射到upstream组192.168.0.55:8080和192.168.0.206:8080,那如何配置做到访问192.168.0.219:8 ...

  9. 【Mac + Mysql + Navicat Premium】之Navicat Premium如何连接Mysql数据库

    参考文章: <mac用brew安装mysql,设置初始密码> 因为我需要连接数据库工具,需要密码,所以下面介绍如何设置.修改密码实现Navicat Premium连接Mysql数据库 建议 ...

  10. 在Ubuntu下利用Eclipse开发FFmpeg配置小结

    首先需要编译FFmpeg得到头文件和lib文件,参见:在Ubuntu下编译FFmpeg 选择File-New-C Project 选择Executable下的Empty Project,右侧选择Lin ...