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

《Effective Java》这本书吃土已经吃了很长时间,本以为没有线上实战经验,看这本书也看不懂,但是今天打开看了一下,发现还是有一部分能够看懂。下面就将自己所看所感记录下来。顺便再多说一嘴,其实有时候记笔记,不是为了后面回头再去复习,只是为了当前记忆更加深刻。

在过去的Java编程中,为了得到不同的对象,最常用的方法就是用不同的构造器去生成一个对象,很少能够想到用静态工厂方法去生成对象。下面是一个来自 Boolean 的简单实例

public static Boolean valueOf( boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;
}

静态工厂方法的优点

静态工厂方法与构造器不同的第一大优势在于,它们有名称

如果使用构造器去生成不同的对象,不同的对象需要不同的参数的去区分。如果使用有名称的静态工厂方法去生成对象,这样就会便于阅读和理解。例如:
BigInteger(int, int, Random) 返回的 BigInteger 可能为素数,如果用名为 BigInteger.probablePrime 的静态工厂方法来表示,显然更为清楚。

静态工厂方法与构造器不同的第二大优势在于,不必在每次调用它们的时候都创建一个新对象

多次调用静态工厂方法只会在第一次生成对象,究其原因是 static,在Java语言中,static 方法会把生成的对象具有全局生命周期,并且一直保存在内存中。这种方法类似于 Flyweight模式(后期在设计模式分栏中进行介绍)。

静态工厂方法与构造器不同的第三大优势在于,它们可以返回原返回类型的任何子类型的对象

静态工厂方法与构造器不同的第四大优势在于,在创建参数化类型实例的时候,它们使代码变得更加简洁

//JDK 1.6,仅用来说明情况

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

在上面代码中,参数显示的比较冗余。但是有了静态工厂方法,编译器就可以替你找到类型参数。这被称作类型推导(已经在JDK 1.7中实现)。假设 HashMap 提供了这个静态工厂:

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

然后就可以使用下面代码代替上面繁琐的声明
Map<String, List<String>> m = HashMap.getInstance()

每一种方法不仅有优点,而且也会存在缺点,下面是静态工厂方法的缺点

静态工厂方法的缺点

静态工厂方法的主要缺点在于,类如果不含公有的或者受保护的构造器,就不能被子类化

静态工厂方法的第二个缺点在于,它们与其他的静态方法实际上没有任何区别

说点什么

avatar
  Subscribe  
提醒

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部