重读《Effective Java》- 创建和销毁对象

806 阅读3分钟

阿里工作5年面试官分享Java面试,文章首发在公众号:liebao小奕,回复1024获取Java开发扫盲思维导图。回复加群进粉丝群。

前言

重读《Effective Java》- 开头篇


1.1 考虑用静态工厂方法代替构造器

静态工厂方法和构造器都可以创建对象实例,不同在于前者 语意更加显性化。

public BigInteger(int,int,Random) 返回的可能是素数,如果用名称BigInter.probablePrime静态方法表示对于使用者更加清楚

静态工厂方法在创建参数化实例时,可以使代码更加简洁。
Map<String,List<String>> map = new HashMap<String,List<String>>();

如果泛型类型参数越来越多,那么这将会变得冗长起来。但是有静态工厂方法,编译器可以做到类型推导,假设HashMap提供了这样一个静态方法:

public static <K,V> HashMap<K,V> newInstance() {
    return new HashMap<K,V>();
}

那么你在使用的时候就可以这样使用

Map<String,List<String>> map = HashMap.newInstance();

静态工厂方法和普通静态方法本质没有什么区别,一般我们规范中静态工厂方法惯用名称如下: valueOf getInstance newInstance of newType 等来区分。

1.2 遇到多个构造器参数优先考虑构建器

静态工厂和构造器有个共同的局限性,不能很好扩展大量可选参数。

考虑使用Javabeans模式,先调用无参构造生成对象,通过setter方法来赋值属性,但是这种模式它在构造过程中被分到了几个调用中,无法通过校验构造器参数的有效性来保证对象的一致性。

考虑使用builder模式,它能满足Javabeans模式那样的可读性,但是为了创建对象,必须先创建它的构建器,平时实践中这种开销可能不那么明显。

1.3 通过私有构造器强化不可实例化的能力

有一些比如工具类,是不想被实例化的,可以使用私有的构造方法,来避免实例化:

public class JsongUtil{
    private JsongUtil(){}
}

1.4 消除过期的对象引用

常见的是在栈操作,出栈操作并不意味着释放对象。

public Object pop(){
    if(size == 0)
        throw new EmptyStackException();
    Object result = elements[--size];
    elements[size] = null;
    return result;
}

1.5 避免创建不必要的对象

能重用对象尽量重用对象无需创建一个相同功能的对象。即创建出来的对象是不可变的,那么它将会被重用。

String str = new String("小奕Java");

该语句每次执行都会创建一个新的String实例,如果这种用法在一个循环中,或者频繁调用将会创建很多不必要的实例。可以改造成如下写法:

String str = "小奕Java";

这种写法只会有一个实例,并且可以保证在同一JVM中,对象均可重用。

最后

  • 文章均原创,原创不易,感谢掘金平台,觉得有收获,帮忙三连,笔芯
  • 文章涉及的所有代码、时序图、架构图均共享,可通过公众号留言获取
  • 文章若有错误,欢迎评论留言指出,也欢迎转载,麻烦标注下出处就好