Java 静态工厂方法每次调用时都创建一个新对象
在有效的Java中,its提到“与构造函数不同,静态工厂方法不需要在每次调用时创建新对象” 在主要课堂上:Java 静态工厂方法每次调用时都创建一个新对象,java,static,factory,Java,Static,Factory,在有效的Java中,its提到“与构造函数不同,静态工厂方法不需要在每次调用时创建新对象” 在主要课堂上: Car c2 = Car.redCar(); Car c3 = Car.redCar(); c2和c3是不同的对象。我没有得到“每次调用时不需要创建新对象”的上下文。因为这就是您要做的: public static Car redCar(){ return new Car("red"); } // ^ here 如果要返回相同的
Car c2 = Car.redCar();
Car c3 = Car.redCar();
c2和c3是不同的对象。我没有得到“每次调用时不需要创建新对象”的上下文。因为这就是您要做的:
public static Car redCar(){
return new Car("red");
}
// ^ here
如果要返回相同的值,可以执行以下操作:
private static final Car RED_CAR = new Car("red");
public static Car redCar(){
return RED_CAR;
}
关键是调用newcar()
总是会返回一个新实例。调用Car.newInstance()
意味着Car
类可以决定做什么
例如:
private static final Map<String, Car> CARS = new HashMap<>();
public static Car newInstance(final String colour){
return CARS.computeIfAbsent(colour, Car::new);
}
Bloch描述的思想是,静态工厂可以使用它在被请求时传递的实例的池或缓存,或者决定其内部逻辑来创建一个新实例(这也可能进入缓存)。这通常只适用于不可变对象,否则会产生一些难以跟踪的跨对象效果。您给出的实现不是静态工厂。您已按如下方式完成课程:
class Car{
String color;
Boolean spoiler;
public static final Car car = new Car("name");
public Car getInstance(){
return car;
}
private Car(String s){
color=s;
spoiler = false;
}
public static Car redCar(){
return new Car("red");
}
}
and then in main you have to call
Car.getInstance();
也许汽车不是最好的例子,但考虑到一个要求,你的工厂应该只生产一辆车每种颜色。您可以这样实现它(省略不必要的属性):
等级车{
字符串颜色;
公共汽车(字符串颜色){
这个颜色=颜色;
}
公共静电车(串色){
Car=CARS.get(颜色);
如果(car!=null)返回car;
车=新车(颜色);
汽车。放置(颜色、汽车);
返回车;
}
私有静态最终映射车=新HashMap();
}
看看这个类及其工厂方法。此外,这种工厂方法对于单例是有用的(尽管它们有自己的警告)。这里您正在创建新对象
return new Car("red");
静态工厂方法将用于第一次创建对象,然后在下次从静态工厂方法返回时返回相同的实例。与其他方法一样,程序完全按照您的要求执行。如果静态方法每次调用时都使用“new”;然后每次创建新对象
与构造函数不同的是,静态工厂方法不需要在每次调用时创建新对象“
是因为您的代码可以决定不调用new;例如,返回一个“缓存”对象
含义:当您使用“new”时,您调用构造函数;Java的语义导致创建一个new对象。没有办法阻止had,它是硬连接到语言中的
但是,当您使用静态方法时,您定义了该方法的语义。“与构造函数不同,静态工厂方法在每次调用时都不需要创建新对象”。这并不意味着调用静态工厂方法必然返回相同的对象(如您的示例所示),只有它可能(与构造函数不同)
例如,您可以以不同的方式实现redCar()
,使其始终返回相同的对象:
class Car{
/* snipped */
private static final RED = new Car("red");
public static Car redCar(){
return RED;
}
}
Factory的任务是创建对象。如果不想公开对象的创建方式,请将创建隐藏在Factory下 最近,我碰巧在处理一个用例,其中基于一些附加的限制定义了单例的概念。例如,捕获file1.txt的所有文件对象都是单例的(或是相同的对象)。同样,捕获file2.text的文件对象也是单例的。但是,捕获file1.text和file2.text的文件对象是不同的 为此,请创建一个静态全局列表,添加所谓的静态对象(例如,基于文件名)。如果不希望将单例(同样基于文件的)对象添加到此列表,请覆盖equals 现在,如果有人要求工厂为您提供一个与您在equals中指定的对象相匹配的对象(任何参数都可以使两个对象相等),请搜索全局列表,如果该对象存在,则返回该对象,否则创建一个新对象,将其添加到列表中,然后返回该对象
这个故事的寓意是,你不必从工厂退回新的物品。你可以根据自己的需要调整单体(如果你不需要纯单体的话)。通过使用静态工厂方法,可以调用ClassName.factory,而不必实例化它。看看什么是单例模式你忘记了本文的重要部分:这允许不可变的类(第15项)若要使用预构造的实例,或在构造实例时缓存实例,并重复分发它们以避免创建不必要的重复对象,请错过“不需要”部分。您的实现每次都明显返回新实例。或
cars.computeIfAbsent(颜色,Car::new)
,请参阅。此外,请遵守Java命名约定,编译时常量应为大写字母\u下划线\u大小写
。
class Car {
String color;
public Car(String color) {
this.color = color;
}
public static Car car(String color) {
Car car = CARS.get(color);
if (car != null) return car;
car = new Car(color);
CARS.put(color, car);
return car;
}
private static final Map<String, Car> CARS = new HashMap<>();
}
return new Car("red");
class Car{
/* snipped */
private static final RED = new Car("red");
public static Car redCar(){
return RED;
}
}