In JavaFX, there are a few classes, for example javafx.scene.text.Font and javafx.scene.paint.Color that have static methods that act like constructors. In the Font class, it is possible to create a new Font object with the statement new Font(name, size)
, but it is equivalent to calling the static method Font.font(name, size)
, where the Font.font method returns the reference to a new Font object. What are the objective benefits that JavaFX gains from creating these ‘static’ constructors? They seem redundant. Why not just declare more overloaded constructors to achieve the same goal?
CodePudding user response:
In general, there are several advantages and disadvantages to using static factory methods compared to using constructors. A good reference for this is Joshua Bloch's "Effective Java" (which I strongly recommend any Java programmer should read); in the second and third editions it is Item 1.
For the specific classes you mention:
Color
Since factory methods have names, using factory methods allows for multiple methods with the same signature. E.g.
public static Color color(double red, double green, double blue);
public static Color hsb(double hue, double saturation, double brightness);
These could not be replaced by two different constructors, as they would be ambiguous.
Additionally, it could be argued that the factory methods provide more descriptive names. For example, the two methods
public static Color valueOf(String value);
public static Color web(String colorString);
have exactly the same functionality, but both are valuable from a design perspective. The valueOf()
method allows for interaction with the FXMLLoader
, whereas the web(...)
method is more appropriately named (it takes a string in the same format as is used in the HTML specification).
Font
The rationale for this class is less clear, and knowing the exact reasons would require knowing the mind of the original API designers. However, note that the API specification of the static factory method differs from the constructor:
public static Font font(String family, double size)
Searches for an appropriate font based on the font family name and size. This method is not guaranteed to return a specific font, but does its best to find one that fits the specified requirements. A null or empty value for family allows the implementation to select any suitable font.
public Font(String name, double size)
Constructs a font using the specified full face name and size
As far as I can tell, the current implementation is actually the same, but the API specification allows for that to change in future releases. There may be other benefits too, e.g. the static factory method could cache fonts and return the same instance if that were determined to be a performance enhancement.