Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 静态工厂方法每次调用时都创建一个新对象_Java_Static_Factory - Fatal编程技术网

Java 静态工厂方法每次调用时都创建一个新对象

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 如果要返回相同的

在有效的Java中,its提到“与构造函数不同,静态工厂方法不需要在每次调用时创建新对象”

在主要课堂上:

    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;
     }
}