Nithin
Nithin

Reputation: 338

Static Factory Method is creating a new object everytime its invoked

In Effective Java its mentioned that "Unlike constructors static factory methods are not required to create a new object each time they're invoked".

class Car{
     String color;
     Boolean spoiler;

     public Car(String s){
        color=s;
        spoiler = false;
     }

     public static Car redCar(){
        return new Car("red");
    }
  }

In Main Class:

    Car c2 = Car.redCar();
    Car c3 = Car.redCar();        

c2 and c3 are different objects. I did not get the context of "not required to create a new object each time invoked".

Upvotes: 8

Views: 3564

Answers (8)

Pramod
Pramod

Reputation: 806

Factory's job is to create an object. If you don't want to expose how the object is created, you hide the creation under factory.

Lately I have happened to work on a use case where the concept of singleton is defined based on some added restrictions. E.g., All File objects that capture file1.txt are singleton (or are same object). Similarly File objects that capture file2.text are singleton. However File objects that capture file1.text and file2.text are different.

For this to work, create a static global list that add your so called static objects (e.g., based on file name). If you don't want Singleton (again file based) objects to add to this list override equals.

Now if someone asks the factory to give you an object that matches what you specified in equals (what ever parameters make two objects equal), search the global list and if that object exists return it, else create a new object, add it to the list and then return the object.

The moral of the story is, yo don't have to return new objects from factory. You can bend Singleton to your need (if you don't need pure Singleton). And by using static factory method, one can call ClassName.factory without having to instantiate it.

Upvotes: 1

Seelenvirtuose
Seelenvirtuose

Reputation: 20648

Maybe cars are not the best example, but consider a requirement that says that your factory should produce only one car per color. You would implement it like this (omitting unnecessary attributes):

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

Have a look at the Integer class and its factory method valueOf. Additionally, such a factory method is useful for singletons (although they have their own caveats).

Upvotes: 2

Boris the Spider
Boris the Spider

Reputation: 61168

Because that's what you do:

public static Car redCar(){
    return new Car("red");
}
        //  ^ here

If you want to return the same value you can do something like:

private static final Car RED_CAR = new Car("red");

public static Car redCar(){
    return RED_CAR;
}

The point is that calling new Car() will always return a new instance. Calling Car.newInstance() means that the Car class can decide what to do.

For example:

private static final Map<String, Car> CARS = new HashMap<>();

public static Car newInstance(final String colour){
    return CARS.computeIfAbsent(colour, Car::new);
}

This uses the Car constructor as a method reference to the new Map.computeIfAbsent method, which calls it if a Car of that colour is not already present in the Map. This is a naive (not threadsafe) cache implementation.

So:

final Car one = Car.newInstance("red");
final Car two = Car.newInstance("red");
System.out.println(one == two) // true

Upvotes: 9

Raghuveer
Raghuveer

Reputation: 3057

The implementation you have given is not a static factory. You have make the class as below:

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();

Upvotes: 0

Mureinik
Mureinik

Reputation: 311948

"Unlike constructors static factory methods are not required to create a new object each time they're invoked". This does not mean calling a static factory method will necessarily return the same object (as your example shows), only that it may (unlike a constructor).

You could, e.g., implement redCar() differently so it always returns the same object:

class Car{
     /* snipped */

     private static final RED = new Car("red");

     public static Car redCar(){
        return RED;
     }
}

Upvotes: 4

GhostCat
GhostCat

Reputation: 140553

As in everything, programs do exactly what you ask them to do. If your static method uses "new" each time when it is called; then you create new object each time.

What is meant by unlike constructors static factory methods are not required to create a new object each time they're invoked" is the fact that your code can decide to not call new; but for example return a "cached" object.

Meaning: when you use "new"; you call constructors; and the semantics of Java lead to the creation of a new object. There is no way preventing had, it is hardwired into the language.

But when you use static methods, you define the semantics of that method.

Upvotes: 2

user2408578
user2408578

Reputation: 464

Here you are creating new objects,

return new Car("red");  

Static factory methods will be used to create object once for the first time and then return same instance next time when returned from static factory methods.

Upvotes: 1

LastFreeNickname
LastFreeNickname

Reputation: 1455

The idea Bloch describes is that a static factory can use a pool or cache of instances that it passes when requested or decide on its inner logic to create a new instance (which may make into the cache too). This usually works only for immutable objects as otherwise you'd have some hard-to-track cross object effects.

Upvotes: 0

Related Questions