java的静态工厂方法

1.什么是静态工厂方法

类可以提供一个共有的静态工厂方法(static factory method),它只是一个放回类的实例的静态方法。
下面是一个来自Boolean(基本类型boolean的装箱类)的简单实例。

/** 将boolean基本类型转换成了一个Boolean对象引用*/
public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
}

知识点:new 究竟做了什么?
简单来说:在JAVA里就是创建一个新的实例,或者说一个新的对象,一个普通类在没有实例化之前,就是new之前,它的属性,方法等等在内存中都是不存在的。只有使用new了以后,这个类的一些东西在内存中才会真的存在,也就是说只有new了之后,这个类才能用。

2.静态工厂方法的优势

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

如:BigInteger(int,int,Random)返回的BigInteger可能为素数,如果用名为
BigInteger.probablePrime的静态工厂方法来表示,显示更为清楚。

/** BigInteger(int,int,Random)*/
    public BigInteger(int bitLength, int certainty, Random rnd) {
        BigInteger prime;

        if (bitLength < 2)
            throw new ArithmeticException("bitLength < 2");
        prime = (bitLength < SMALL_PRIME_THRESHOLD
                                ? smallPrime(bitLength, certainty, rnd)
                                : largePrime(bitLength, certainty, rnd));
        signum = 1;
        mag = prime.mag;
    }
/**  BigInteger.probablePrime*/
   public static BigInteger probablePrime(int bitLength, Random rnd) {
        if (bitLength < 2)
            throw new ArithmeticException("bitLength < 2");

        return (bitLength < SMALL_PRIME_THRESHOLD ?
                smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
                largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));
    }

2.2 第二大优势在于,不必再每次调用他们的时候都创建一个新的对象。

这使得不可变类可以使用预先构建好的实例,或者将构建好的实例缓存起来,进行重复利用,从而避免创建不必要的重复对象。实例受控是的类可以确保他是一个单例或者是不可实例化的。

/** 不能通过构造器创建*/
	private Sort(Direction direction, List<String> properties) {

		if (properties == null || properties.isEmpty()) {
			throw new IllegalArgumentException("You have to provide at least one property to sort by!");
		}

		this.orders = properties.stream() //
				.map(it -> new Order(direction, it)) //
				.collect(Collectors.toList());
	}
/** 通过静态工厂方法创建*/
	public static Sort by(Direction direction, String... properties) {

		Assert.notNull(direction, "Direction must not be null!");
		Assert.notNull(properties, "Properties must not be null!");
		Assert.isTrue(properties.length > 0, "At least one property must be given!");

		return Sort.by(Arrays.stream(properties)//
				.map(it -> new Order(direction, it))//
				.collect(Collectors.toList()));
	}

2.3 第三大优势在于,它们可以放回原返回类型的任何子类型的对象。

2.4 第四大优势在于,返回的对象的类可以随着每次调用而发生变化,这取决与静态工厂的参数。

/** 通过泛型的床底改变放回值 */
    public static <E extends Enum<E>> EnumSet<E> of(E e) {
        EnumSet<E> result = noneOf(e.getDeclaringClass());
        result.add(e);
        return result;
    }

2.5 第五大优势在于,方法返回的对象所属的类,在编写包含该静态工厂方法的类是可以不存在。

/** 返回Connection,该类为DriverManager.class */
    @CallerSensitive
    public static Connection getConnection(String url,
        java.util.Properties info) throws SQLException {

        return (getConnection(url, info, Reflection.getCallerClass()));
    }

3.静态工厂方法的缺点

  • 3.1 类如果不包含共有的或者受保护的构造器,就不能被子类化。
  • 3.2 程序员很难发现静态工厂方法。

4.总结

简而言之,静态工厂方法和公有构造器都有用处,我们需要理解他们各自的长处。静态工厂经常更加合适,因此切忌第一反应就是提供公有的构造器,而不先考虑静态工厂。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值