0

Started reading "Effective java" and can't understand why it doesn't work for me when I try coding an example..

Compile error:

Error:(12, 16) java: constructor Car in class Car cannot be applied to given types;


public class Car {

    String model;

    //no private constructor

    public static Car fromModel(String model) {
        return new Car(model);
    }

}

Here everything is OK:

public class Car {

    String model;

    //no private constructor

    public static Car fromModel(String model) {
        return new Car(model);
    }
}

//Here everything is OK:

public class Car {

    String model;

    private Car(String model) {
        this.model = model;
    }

    public static Car fromModel(String model) {
        return new Car(model);
    }

}

Why should I generate constructor if "Consider static factory methods instead of constructors" ???

Jacob
  • 168
  • 2
  • 13

3 Answers3

1

"Consider static factory methods instead of constructors" refers to providing access to instantiation of your objects to users of your library outside your class.

The constructor that your factory method uses is an implementation detail of your factory method in the same way as the static public method - the method and the private constructor together constitute one factory method for outside users of your class library.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • If I understand it correctly I must have one private constructor with all variables and then can have several private static methods? – Dmytro Manzhula May 12 '18 at 18:49
  • @mnjl Although this is a very common way of implementing the pattern, the specifics are up to you. You can define multiple private constructors if it is more convenient for you. – Sergey Kalinichenko May 12 '18 at 18:51
0

The answer for me is that I need at least one private constructor to make several static methods.

No compilation errors:

public class Car {

String model;
String color;
String modelYear;

private Car(String model, String color, String modelYear) {
    this.model = model;
    this.color = color;
    this.modelYear = modelYear;
}

public static Car fromModelAndColor(String model, String color){
    return new Car(model, color, null);
}

public static Car fromModelAndYear(String model, String modelYear){
    return new Car(model, null, modelYear);
}

public static Car fromModelAndColorAndYear(String model, String color, String modelYear){
    return new Car(model, color, modelYear);
}

}

  • 1
    Before I supposed that I don't need any constructor, because: "Consider static factory methods instead of constructors". Now I can see I was misled ... And discussion above much clarified my question. I've just edited my answer. – Dmytro Manzhula May 12 '18 at 19:46
0

Your example may be very simple. Plain constructor may have either large number of parameters. In such cases you could "name" each constructor by creating a static constructor method. Secondly using this pattern you could hide part of constructor parameters.

Example:

class FinishEvent {
   privare Car response;
   private boolean success;
   private String errorMessage;

  //private constructor, we delegate creating to named methods
   private FinishEvent(Car response, boolean success, String errorMessage) {... } 

}

As you can see Car is an response here, but when Event is a success, we don't need errorMessage to be filled. On the other hand, if the process is failed, we don't have a response to fill in.

Here static constructor methods come in handy:

public static FinishEvent success(Car response){
  return new Car(response, true, null);
}
public static FinishEvent failed(String errorMessage){
  return new Car(null, false, errorMessage);
}

Having this API other users of your class, know how to use it.

If your Car would be an abstract method, then your factory methods could provide implementations. That way you could hide all implementations from user, but provide a way to create them.

Beri
  • 11,470
  • 4
  • 35
  • 57
  • suppose I got it. Please check my downvoted answer below, it looks correct for me according to your explanation...Thanks! – Dmytro Manzhula May 12 '18 at 19:30
  • @mnjl true, your answer is correct, but pasting code with no explanation does not count as an answer. It could be a copy paste, or another plagiat. Please add some comments:) – Beri May 12 '18 at 19:40
  • Done, please give feedback if it still lacks of clarification. – Dmytro Manzhula May 12 '18 at 19:50