在Effective Java中,它提到"与构造函数不同,静态工厂方法在每次调用时都不需要创建新对象"。
class Car{
String color;
Boolean spoiler;
public Car(String s){
color=s;
spoiler = false;
}
public static Car redCar(){
return new Car("red");
}
}
在大班:
Car c2 = Car.redCar();
Car c3 = Car.redCar();
c2和c3是不同的对象。我没有得到"每次调用时都不需要创建新对象"。
答案 0 :(得分:7)
因为你做的是:
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;
}
关键是调用new Car()
将总是返回一个新实例。调用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);
}
这会将Car
构造函数用作新method reference方法的Map.computeIfAbsent
,如果Car
中没有Map
的颜色,则会调用它1}}。这是一个天真的(不是线程安全的)缓存实现。
所以:
final Car one = Car.newInstance("red");
final Car two = Car.newInstance("red");
System.out.println(one == two) // true
答案 1 :(得分:3)
&#34;与构造函数不同,静态工厂方法不是必需,以便在每次调用&#34;时创建新对象。这并不意味着调用静态工厂方法将必然返回相同的对象(如示例所示),只是可能(与构造函数不同)。
您可以,例如,以不同方式实现redCar()
,因此它始终返回相同的对象:
class Car{
/* snipped */
private static final RED = new Car("red");
public static Car redCar(){
return RED;
}
}
答案 2 :(得分:2)
也许汽车不是最好的例子,但考虑一个要求,即你的工厂应该每种颜色只生产一辆汽车。您可以像这样实现它(省略不必要的属性):
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<>();
}
答案 3 :(得分:1)
您在这里创建新对象
#!/bin/bash
lockpidname="/usr/bin/plasma-overlay --nofork"
$lockpidname
check_slock () {
if [[ $(pgrep -fla $lockpidname) ]]; then
SLOCKED=1
else
SLOCKED=0
fi
}
while true; do
sleep 5
check_slock
case $SLOCKED in
0)
echo "System unlocked run something here"
break
;;
esac
done
静态工厂方法将首次用于创建对象一次,然后在从静态工厂方法返回时返回相同的实例。
答案 4 :(得分:1)
与所有事情一样,程序完全按照您的要求执行。如果静态方法每次调用时都使用“new”;然后每次都创建新对象。
unlike constructors static factory methods are not required to create a new object each time they're invoked"
的含义是您的代码可以决定不调用new;但是例如返回一个“缓存”对象。
含义:当你使用“新”时;你叫构造函数; Java的语义导致创建 new 对象。没有办法防止它,它是硬连线的语言。
但是当你使用静态方法时,你定义该方法的语义。
答案 5 :(得分:1)
工厂的工作是创建一个对象。如果您不想公开对象的创建方式,请在工厂中隐藏创建。
最近我碰巧在一个用例中工作,其中单例的概念是基于一些附加的限制来定义的。例如,捕获file1.txt的所有File对象都是singleton(或者是同一个对象)。类似地,捕获file2.text的File对象是singleton。但是捕获file1.text和file2.text的File对象是不同的。
为此,请创建一个静态全局列表,添加所谓的静态对象(例如,基于文件名)。如果您不希望Singleton(再次基于文件)对象添加到此列表,则覆盖等于。
现在,如果有人要求工厂给你一个与你在equals中指定的对象相匹配的对象(参数使两个对象相等),搜索全局列表,如果该对象存在则返回它,否则创建一个新对象,添加它到列表然后返回对象。
故事的寓意是,你不必从工厂返回新物品。您可以根据需要弯曲Singleton(如果您不需要纯Singleton)。通过使用静态工厂方法,可以调用ClassName.factory而无需实例化它。
答案 6 :(得分:0)
Bloch描述的想法是静态工厂可以使用它在请求时传递的池或缓存实例,或者决定其内部逻辑来创建新实例(可以进入缓存太)。这通常只适用于不可变对象,否则您会有一些难以跟踪的交叉对象效果。
答案 7 :(得分:0)
您提供的实施不是静态工厂。你已经完成了如下课程:
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();