Earyant的技术博客

欢迎来到Earyant的技术博客,在这里我将与你分享新技术。

EffectiveJava读书笔记

EffectiveJava 读书笔记

本文于2017年10月26日再读一遍,对书中的内容进行整理提取,方便以后查阅

[TOC]

第一章:创建和销毁对象

创建对象的方法

  • 构造器方法new一个;
  • 公共静态方法返回实例;
  • Build工程模式。

    一般来说创建对象最简单的方法就是使用的时候new一个,如Person person = new Person();既通过构造器创建对象。这种使用方法不适用于所有情况,例如一个单例工具类,不需要每次使用都new,而是通过一个公共静态方法返回类的实例。

构造器方式

缺点

每一个构造器都与类名相同,无法知其寓意。

构造器方法时最常用的方法;

公共静态方法

优点1

每一个公共静态方法都有名字,顾名思义。

优点2

不必为每次调用都产生一个新的实例,可以重复利用。

优点3

可以返回原返回类型的任何子类型对象。

优点3

创建参数化类型实例,使代码变得更简洁。

缺点1

类如果不含有共有的或者受保护的构造器,就不能被子类化。

缺点2

与其他静态方法没有任何区别。

使用情景1 通过方法名知其方法作用

如BigInteger(int,int,Random)返回的BitInteger可能为素数,但如果用BigInteger.probablePrime静态方法来表示,更加清楚方法寓意。

如果两个构造器方法中只是参数类型顺序上不同,很容易造成寓意混乱,需要进一步查询文档才能确定用哪一个,容错率很低。

使用场景2 使用预先定义好的实例。

公共静态方法返回的实例可以控制是否是单例,或者控制是否可以实例化。

  • getInstance和newInstance区别:

    getInstance方法重点是返回已经创建好的实例。
    newInstance方法重点是返回一个新的实例。

使用场景3 Collections的32个便利实现、通过适配器提供更丰富的服务接口

分别提供了不可修改的集合、同步集合等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Service interface
public interface Service{

}

//Service provider interface
public interface Provider{
Service newService();
}

public class Services{
private Services(){};

private static final Map<String,Provider> providers = new ConcurrentHashMap<String,Provider>();

public static final String DEFAULT_PROVIDER_NAME = "<def>";

public static void registerDefaultProvider(Provider p){
registerProvider(DEFAULT_PROVIDER_NAME,p););
}

public static void registerProvider(String name,Provider p){
providers.put(name,p);
}

public static Service newInstance(){
return newInstance(DEFAULT_PROVIDER_NAME);
}

public static Service newInstance(String name){
Provider p = provider.get(name);
if(p == null){
throw new IllegalArgumentException("No provider registered with name:"+ name);
}
return p.newService();
}
}

使用场景4 代替繁琐的参数声明。

使用场景6

valueOf — 返回的实例与参数具有相同的值,实际上是类型转换方法。
of — valueOf的简洁替代。
getInstance — 返回的实例是通过方法的参数来描述的,但是不能说与参数有相同的值。对于Singleton来说,该方法没有参数。
newInstance — 跟getInstance一样,但是该方法确保返回的实例与其他实例不同。
getType — 跟getInstance一样,但是在工厂方法中处于不同的类中的时候使用,Type表示工厂方法锁返回的对象类型。
newType — 像newInstance一样,但是在工厂方法中处于不同的类中的时候使用。

构建器

静态工厂和构造器都有个局限性,都不能很好的扩展到大量的可选参数。
参数量大的情况下通常有两种方法:

  • 重叠构造器

    可行,但很难编写,难以阅读。

  • 工厂模式

    build构造参数很简单明了,链式调用很少出错。
    但是在构造Bean的时候,可能出现不一致的状态,类无法仅仅通过构造器参数的有效性来保证一致性。

用私有构造器或者枚举类型强化Singleton属性

构造器私有,公开一个公共静态方法返回实例。

欢迎关注我的其它发布渠道