effective java观后感(1)-------用静态方法代替构造方法
来源:互联网 发布:iphone用mac充电 编辑:程序博客网 时间:2024/06/08 09:58
Effective Item - 考虑用静态工厂方法代替构造器我们有两种常见的方法获得一个类的实例:
- 公有的构造器
- 提供静态工厂方法(static factory method)
相对公有的构造器,静态工厂方法有以下几大优势。
优势1.静态工厂方法的名称,因此比构造器更准确地描述返回的实例。
比如BigInteger.probablePrime方法:
public static BigInteger probablePrime(int bitLength, Random rnd) { if (bitLength < 2) throw new ArithmeticException("bitLength < 2"); // The cutoff of 95 was chosen empirically for best performance return (bitLength < SMALL_PRIME_THRESHOLD ? smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) : largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));}
顺便也贴出其调用的largePrime方法:
private static BigInteger largePrime(int bitLength, int certainty, Random rnd) { BigInteger p; p = new BigInteger(bitLength, rnd).setBit(bitLength-1); p.mag[p.mag.length-1] &= 0xfffffffe; // Use a sieve length likely to contain the next prime number int searchLen = (bitLength / 20) * 64; BitSieve searchSieve = new BitSieve(p, searchLen); BigInteger candidate = searchSieve.retrieve(p, certainty, rnd); while ((candidate == null) || (candidate.bitLength() != bitLength)) { p = p.add(BigInteger.valueOf(2*searchLen)); if (p.bitLength() != bitLength) p = new BigInteger(bitLength, rnd).setBit(bitLength-1); p.mag[p.mag.length-1] &= 0xfffffffe; searchSieve = new BitSieve(p, searchLen); candidate = searchSieve.retrieve(p, certainty, rnd); } return candidate;}
虽然smallPrime和largePrime最后都是通过公有构造器返回实例。
但是如果仅仅用构造器重载表达这个实例的特征,这很难让人记住什么时候应该调用什么构造器。
而提供一个名称去描述实例更为直观。
优势2.静态工厂方法不必每次都创建一个新的对象,我们可以对实例进行控制。
这样我们就能将创建好的实例缓存起来重复利用,尤其是在创建对象的代价较高的情况下。
比如Boolean.valueOf:
public static final Boolean TRUE = new Boolean(true);public static final Boolean FALSE = new Boolean(false);public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE);}
优势3.静态工厂方法可以返回原返回类型的子类型对象。
这一点能体现静态工厂方法的灵活性,
以EnumSet为例:
/** * Creates an empty enum set with the specified element type. * * @param elementType the class object of the element type for this enum * set * @throws NullPointerException if <tt>elementType</tt> is null */public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) { Enum[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); if (universe.length <= 64) return new RegularEnumSet<>(elementType, universe); else return new JumboEnumSet<>(elementType, universe);}
而RegularEnumSet和JumboEnumSet为EnumSet的子类,并且都没有提供公有构造器。
优势4.静态工厂方法创建参数化(泛型)实例的时候更加简洁。
举个例子:
public static <K, V> HashMap<K, V> newInstance() { return new HashMap<K, V>();}
这样一来创建实例时就可以:
Map<String,List<Integer>> n = newInstance();
而不是
Map<String,List<Integer>> m = new HashMap<String,List<Integer>>();
从Java7开始这一点变得没有意义,事实上Josh Bloch也在书上提到了这点——Java以后会在构造器和方法调用中执行这种类型推导。
说说静态工厂方法的缺点。
- 类如果不含公有或者受保护的构造器就不能被子类化。
所以上面说的静态工厂方法可以返回原返回类型的子类型对象。并不完全正确。
虽然我们可以通过复合方式(composition)解决这一问题,但这样两个类就不是is-a关系了。 - 静态工厂方法的本质还是静态方法,他没有一个特别的标准。
我们无法在API文档中把一个静态工厂方法特别标识出来(也许可以加个标准annotation?)。
当我要从API中找一个方法去实例化一个类时,相对构造器而言还是不够直观。
虽然没有特个特别的标准,但我们也可以用标准的命名来弥补一点点。
比如valueOf,getInstance,newInstance,newType等...
原文地址:http://www.cnblogs.com/Kavlez/p/4224826.html
0 0
- effective java观后感(1)-------用静态方法代替构造方法
- 《Effective Java》: 考虑用静态工厂方法代替构造函数
- [Effective Java]考虑用静态工厂方法代替构造器
- 《Effective Java》-考虑用静态工厂方法代替构造器
- Effective Java -- 用静态工厂方法来代替构造器
- Effective Java (1) - 考虑用静态工厂方法代替构造器
- [Effective Java] 第1条 考虑用静态工厂方法代替构造函数
- Effective Java记录1:考虑用静态工厂方法代替构造器
- 《Effective java》读书记录-第1条-考虑用静态工厂方法代替构造器
- 1、考虑用静态工厂方法代替构造器(effective java)
- Effective Java 读书笔记——1:考虑用静态工厂方法代替构造器
- Effective Java 中文版之学习 第1条:考虑用静态工厂方法代替构造器
- Effective Java 1 -- 考虑用静态工厂方法代替构造器
- effective java--关于静态工厂方法代替构造器
- 读书笔记-《Effective java 》之 考虑静态方法代替构造器
- 【Effective Java学习】创建和销毁对象--考虑用静态方法代替构造器
- Effective java读书札记第一条之 考虑用静态工厂方法代替构造器
- Effective JAVA NO1考虑用静态工厂方法代替构造器
- 我来了
- 精简代码真心是个技术活
- 我来了
- 输出梯形列的数字
- 我来了
- effective java观后感(1)-------用静态方法代替构造方法
- Android热修复实践应用--AndFix
- 正则表达式验证用户名、邮箱、密码
- VitamioDemo
- 我来了
- 为什么你有10年经验,但成不了专家?
- PyMongo基本使用
- 我来了
- 代码克隆的类别总结