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

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

  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. SDUT 2766-小明传奇2(母函数)

    小明传奇2 nid=24#time" title="C.C++.go.haskell.lua.pascal Time Limit1000ms Memory Limit 65536K ...

  2. html禁止图片拖拽移动在新窗口打开

    一直觉得直接从网站的表格上复制数据挺方便的, 今天,领导突然说网站上的图片可以被别人拖走了,必须禁止,哎,果然只有领导才考虑得到这种事情啊 so, 将ondragstart="return ...

  3. 零基础学python-1.5 第一个程序

    这一个章节我们来说说怎么建立一个python程序 1.打开idle 2.点击File->new file,然后会弹出一个编辑窗体 3.在编辑窗体里面输入命令代码 程序代码: print(&quo ...

  4. mysql更改表结构:添加、删除、修改字段、调整字段顺序

    添加字段: alter table `user_movement_log` Add column GatewayId int not null default 0 AFTER `Regionid` ( ...

  5. Google 商店

    Google 商店地址:https://store.google.com/

  6. Sphinx初探之安装

    在Centos or redhat 安装Sphinx .首先安装依赖包 $ yum install postgresql-libs unixODBC .安装软件 $ rpm -Uhv sphinx-- ...

  7. Android linux kernel privilege escalation vulnerability and exploit (CVE-2014-4322)

    In this blog post we'll go over a Linux kernel privilege escalation vulnerability I discovered which ...

  8. 【LeetCode-面试算法经典-Java实现】【114-Flatten Binary Tree to Linked List(二叉树转单链表)】

    [114-Flatten Binary Tree to Linked List(二叉树转单链表)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a bin ...

  9. 403/you don't have the permission to access on this server

    Localhost/index.php出现 错误403 you don't have the permission to access on this server 现在已经解决,特将方法与大家分享. ...

  10. Spring WebSocket Support官方文档+翻译

    实时更新技术能够应用在很多场景中,比如在浏览器中聊天.股票报价.状态更新.现场直播.这些需求对时间的延迟性都很敏感,但是我们可以发现他们存在这共有的共性. 标准的HTTP请求,是一次请求对应一次相应. ...