effective java观后感(1)-------用静态方法代替构造方法

转载 2016年08月31日 14:52:00

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

[Effective Java Distilled] Item 1 考虑使用静态工厂方法来替换构造方法

关于Effective Java Distilled: 《Effective Java》这本书我断断续续的读了近两遍,里面的内容挺有深度,对提高工程代码质量也非常有帮助。我打算慢慢的整理出来一个系列...

[Effective Java]第一话:使用静态工厂方法代替构造方法

一、Item 1:Consider static factory methods instead of constructors(使用静态工厂方法代替构造方法)优点: 其一、不同于构造方法,静态工...

《Effective Java》读书笔记01-静态方法与构造器

一、序言 程序设计的几条基本原则: 1、清晰性和简洁性最为重要,模块的用户永远也不应该被模块的行为所迷惑,所以写良好的注释是必需的。 2、模块要竟可能小,但也不能太小,好一个深奥的哲学问题。 ...

Java性能优化(1):用静态方法代替构造函数

对于一个类,为了让客户获得它的一个实例,最通常的方法是提供一个公有的构造函数。实际上还有另外一种技术,尽管较少为人所知,但也应该成为每个程序员的工具箱中的一部分。...

JAVA 构造方法 静态方法

构造方法 作用: 对 对象的属性(成员变量)进行初始化 写法: 1.构造方法的方法名与类名完全相同 2.没有返回值类型(连void都不写) 3.没有返回值注意事项: 1.没写构造方法 ...

Effective Java (1) - 考虑用静态工厂方法代替构造器

一、前言 从今天开始计划用半个月的时间,写十篇读书笔记来记录阅读这本Java领域号称经典中的经典书籍-Effective Java(高效Java)过程中自己所思所想,以备以后查阅,同时分享出去也希望...
  • zdp072
  • zdp072
  • 2013年12月21日 21:33
  • 5009

Effective Java(1)考虑静态工厂方法代替构造器

因为各种原因,好久没有来CSDN写博客了。今天决定

Effective Java记录1:考虑用静态工厂方法代替构造器

静态工厂方法与构造器不同之处在于 1.它们有名称 2.不必在每次调用时,创建新对象 3.多态性,可以返回原类型,或者其子类型 代码说明 // 服务接口 public interfac...

Effective Java 1:考虑使用静态工厂方法代替构造器

最近在看Effective Java,第一条是考虑使用静态工厂方法代替构造器。优点 静态工厂方法与构造方法不同的是它们有方法名称 不必每次调用它们的时候创建一个新的对象 它们的返回类型可以是任何子类型...

1、考虑用静态工厂方法代替构造器(effective java)

考虑静态构造方法这里的静态构造方法不等于设计模式中的工厂模式public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:effective java观后感(1)-------用静态方法代替构造方法
举报原因:
原因补充:

(最多只允许输入30个字)