1. 什么是静态工厂方法
Java中的静态工厂方法是指在类中定义一个静态方法,返回类自身对象或其子类对象,用于创建实例对象的过程。一般情况下,静态工厂方法参数不同,可以创建不同的实例对象返回。
静态工厂方法示例:
public class Car {
private String brand;
private String color;
private Car(String brand, String color) {
this.brand = brand;
this.color = color;
}
public static Car createRedCar(String brand) {
return new Car(brand, "Red");
}
public static Car createGreenCar(String brand) {
return new Car(brand, "Green");
}
// getter and setter
}
2. 静态工厂方法的优势
2.1 灵活性
静态工厂方法的返回值可以是任意子类对象,而构造器只能返回当前类对象。这意味着我们可以创建更为灵活的对象,针对不同的参数选择不同的子类进行返回,满足不同需求。
例如,自行车厂家生产自行车的方法:
public class Bicycle {
// ...
}
public class MountainBike extends Bicycle {
// ...
}
public class RoadBike extends Bicycle {
// ...
}
public class BicycleFactory {
public static Bicycle createBicycle(String type) {
switch (type) {
case "MountainBike":
return new MountainBike();
case "RoadBike":
return new RoadBike();
default:
return new Bicycle();
}
}
}
2.2 可读性
静态工厂方法可以有具有描述性的方法名称,增强代码可读性和可维护性,以及更好地阐述实例对象的创建过程。例如,我们使用单例模式时,可以使用getInstance
方法来获取单例对象,而不必使用new
关键字。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
// ...
}
2.3 封装性
静态工厂方法对于实现类和调用类之间可以起到更好的封装性,不必公开构造器,防止被外部直接调用。同时也可以提供更好的安全性和易用性。例如,我们可以定义File
类的静态工厂方法,来创建File
对象:
public class File {
private String name;
private String path;
private File(String name, String path) {
// ...
}
public static File createFile(String name, String path) {
// 判断是否存在同名文件
// 判断文件权限是否足够
// 创建并返回实例对象
return new File(name, path);
}
// ...
}
2.4 性能
静态工厂方法可以重载,提高代码灵活性,同时也可以优化代码性能。例如,valueOf
方法可以将输入参数转换为内部类型或对象,并且可以优化空间和时间效率。
public class Integer {
private final int value;
private Integer(int value) {
this.value = value;
}
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high) {
return IntegerCache.cache[i + (-IntegerCache.low)];
}
return new Integer(i);
}
// ...
}
2.5 可控性
静态工厂方法可以通过缓存等方式来控制类实例的数量,避免不必要的实例创建,从而提高性能。
例如,我们创建一个对象池,来管理对象的创建与销毁。
public class ObjectPool<T> {
private final List<T> pool = new ArrayList<>();
public ObjectPool(Supplier<T> supplier, int size) {
for (int i = 0; i < size; i++) {
pool.add(supplier.get());
}
}
public T borrow() {
if (pool.size() > 0) {
return pool.remove(pool.size() - 1);
}
return null;
}
public void recycle(T t) {
pool.add(t);
}
}
3. 总结
静态工厂方法在维护性、安全性、性能等方面都有比较大的优势,提倡在Java中使用静态工厂方法取代构造器来创建实例对象。同时,我们也需要结合具体业务需求确定是否需要使用静态工厂方法,不能过度使用。