`

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

 
阅读更多

一、前言

从今天开始计划用一个月的时间,通过写读书笔记的方式来记录阅读这本Java领域经典中的经典书籍 - Effective Java过程中自己所思所想,以备以后查阅,同时分享出去也希望可以帮助到其他人,废话不多说,现在开始第一篇:创建和销毁对象。


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

①. 一般我们有什么办法可以创建对象呢?

方法1: 使用类公有构造器。

方法2:使用类的静态方法返回一个实例。


②. 使用静态方法创建对象有什么优点?

优点1: 静态工厂方法的名字是由我们自己命名,而构造方法必须与类同名。

PrimeNumber primeNumber1 = new PrimeNumber(int Random); // 返回一个素数
PrimeNumber primeNumber2 = PrimeNumber.newInstance(); // 使用静态工厂方法表示更为清楚
优点2: 构造方法每次调用的时候都需要创建一个对象,而静态工厂方法每次调用的时候就不会创建一个新的对象,这对于一个要频繁创建对象的程序来说,可以极大的提高性能,单例模式就是这样实现的。

优点3: 静态工厂方法可以返回原返回类型的任何子类型的对象,这样使我们在选择返回对象的类时就有了更大的灵活性。

class Father {
	private Father() {
	}
 
	public static Father newInstance(String type) {
		if (type.equals("ChildA")) { // 根据类型判断返回那个子类对象
			return new ChildA();
		} else {
			return new ChildB();
		}
	}

	public void getName() { 
		System.out.println("My name is father");
	}

	private static class ChildA extends Father {
		public void getName() { 
			System.out.println("My name is child A");
		}
	}

	private static class ChildB extends Father {
		public void getName() {
			System.out.println("My name is child B");
		}
	}
}

public class Test {
	public static void main(String[] args) {
		Father c1 = Father.newInstance("ChildA");
		c1.getName();
		Father c2 = Father.newInstance("ChildB");
		c2.getName();
	}
}
优点4: 静态工厂方法在创建参数化类型实例的时候,可以使代码变得更加简洁。
private Map<String, List<String>> map = new HashMap<String, List<String>>();
public static <K, V> HashMap<K, V> newInstance() {
	return new HashMap<K, V>();
}

③. 使用静态工厂方法创建对象有什么缺点?

缺点1: 如果一个类只能通过静态工厂方法来获得实例,那么该类的构造函数就不能是共有的或受保护的,那么该类就不会有子类,即该类不能被继承。单例模式中首先要私有化构造器。

缺点2:静态工厂方法和其他静态方法从名字上看无法区分,所以我们可以约定静态工厂方法名字使用valueOf或者getInstance。


④. 什么时候用静态工厂方法,什么时候用构造器呢?

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


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics