Take the 2-minute tour ×

I've been reviewing Java Regex Library, surprised by the fact the Pattern class does not have a public constructor which I've taken for granted for years.

One reason I suspect the static compile method is being used in favor of constructor could be that constructor would always return a new object while a static method might return a previously created (and cached) object provided that the pattern string is the same.

However, it is not the case as demonstrated by the following.

public class PatternCompiler {
    public static void main(String[] args) {
        Pattern first = Pattern.compile(".");
        Pattern second = Pattern.compile(".");
        if (first == second) {
            System.out.println("The same object has been reused!");
        } else {
            System.out.println("Why not just use constructor?");

Any other strong rationales behind using static method over constructor?

Edit: I found a related question here. None of the answers there convinced me either. Reading through all answers, I get a feeling that a static method has quite a few advantages over a public constructor regarding creating an object but not the other way around. Is that true? If so, I'm gonna create such static methods for each one of my classes and safely assume that it's both more readable and flexible.

share|improve this question
Did you try do dive into the source code? –  Jan Dvorak Dec 7 '12 at 7:30
Perhaps the reason is to ensure readability. –  Jan Dvorak Dec 7 '12 at 7:35
@JanDvorak new Pattern(".") is as readable if not more so, isn't it :) –  Terry Li Dec 7 '12 at 7:36
not if both overloads have the same signature. –  Jan Dvorak Dec 7 '12 at 7:42
What would be gained by adding a constructor? This is an honest question. –  jahroy Dec 7 '12 at 7:51

6 Answers 6

up vote 7 down vote accepted

Generally, a class won't have a public constructor for one of three reasons:

  • The class is a utility class and there is no reason to instantiate it (for example, java.lang.Math).
  • Instantiation can fail, and a constructor can't return null.
  • A static method clarifies the meaning behind what happens during instantiation.

In the class of Pattern, the third case is applicable--the static compile method is used solely for clarity. Constructing a pattern via new Pattern(..) doesn't make sense from an explanatory point of view, because there's a sophisticated process which goes on to create a new Pattern. To explain this process, the static method is named compile, because the regex is essentially compiled to create the pattern.

In short, there is no programmatic purpose for making Pattern only constructable via a static method.

share|improve this answer

One possible reason is that this way, caching can later be added into the method.

Another possible reason is readability. Consider this (often cited) object:

class Point2d{
  static Point2d fromCartesian(double x, double y);
  static Point2d fromPolar(double abs, double arg);

Point2d.fromCartesian(1, 2) and Point2d.fromPolar(1, 2) are both perfectly readable and unambiguous (well... apart from the argument order).

Now, consider new Point2d(1, 2). Are the arguments cartesian coordinates, or polar coordinates? It's even worse if constructors with similar / compatible signatures have entirely different semantics (say, int, int is cartesian, double, double is polar).

This rationale applies to any object that can be constructed in multiple different ways that don't differ in just the argument type. While Pattern, currently, can only be compiled from a regex, different representations of a Pattern may come in the future (admittably, then, compile is a bad method name).

Another possible reason, mentioned by @Vulcan, is that a constructor should not fail.

If Pattern.compile encounters an invalid pattern it throws a PatternSyntaxException. Some people may consider it a bad practice to throw an exception from a constructor. Admittably, FileInputStream does exactly that. Similarly, if the design decision was to return null from the compile method, this would not be possible with a constructor.

In short, a constructor is not a good design choice if:

  • caching may take place, or
  • the constructor is semantically ambiguous, or
  • the creation may fail.
share|improve this answer
+1 very comprehensive and thoughtful! –  Terry Li Dec 7 '12 at 8:05
+1, but I disagree about constructors not supposed to throw exceptions. I nearly included the same argument about exception throwing in my answer, but then I considered the counter-point of new FileInputStream(..) which can throw an IOException. While I agree that throwing exceptions in constructors is messy, it's not an uncommon practice, especially in the java.net and java.io packages. –  Vulcan Dec 7 '12 at 8:08
+1 for the nice example :) –  Dušan Rychnovský Dec 7 '12 at 8:30
Pattern.compile is nothing more than a named constructor. It can and will be called anywhere and everywhere someone would have said new Pattern if they could -- including static init blocks -- and would cause all the same problems. So any advice about avoiding exceptions in constructors should apply to it as well. The rules don't change just because the name does. –  cHao Dec 8 '12 at 4:08
@JanDvorak: Do you have a link or something that says this? I've heard it said in C++, but there are reasons for it there that don't quite apply in Java. –  cHao Dec 8 '12 at 10:13

This is just a design decision. In this case there is no "real" advantage. However, this design allows optimisation (caching for instance) without changing the API. See http://gbracha.blogspot.nl/2007/06/constructors-considered-harmful.html

share|improve this answer
The one more reason is that adding optimisation later into constructor would be a bad practice (passing this while in constructor). Doing the same in a static method is ok. –  Peter Ivan Dec 7 '12 at 8:05

Factory methods have several advantages, some of which are already specified in other answers. The advice to consider factory methods instead of constructors is even the very first chapter in the great book "Effective Java" from Joshua Bloch (a must-read for every Java programmer).

One advantage is that you can have several factory methods which have the same parameter signatures but different names. This you can't achieve with constructors.

For example, one might want to create a Pattern from several input formats, all of which are just Strings:

class Pattern {
  compile(String regexp) { ... }
  compileFromJson(String json) { ... }
  compileFromXML(String xml) { ... }

Even if you are not doing this when you create the class, factory methods give you the ability to add such methods latter without causing weirdness.

For example, I have seen classes where the need for a new constructor came later and a special meaning-less second parameter had to be added to the second constructor in order to allow overloading. Obviously, this is very ugly:

class Ugly {
  Ugly(String str) { ... }

  /* This constructor interpretes str in some other way.
   * The second parameter is ignored completely. */
  Ugly(String str, boolean ignored) { ... }

Unfortunately, I can't remember the name of such a class, but I think it even was in the Java API.

Another advantage which has not been mentioned before is that with factory methods in combination with package-private constructors you can prohibit sub-classing for others, but still use sub-classes yourself. In the case of Pattern, you might want to have private sub-classes like CompiledPattern, LazilyCompiledPattern, and InterpretedPattern, but still prohibit sub-classing to ensure immutability.

With a public constructor, you can either prohibit sub-classing for everybody, or not at all.

share|improve this answer

It has a private constructor.

     * This private constructor is used to create all Patterns. The pattern
     * string and match flags are all that is needed to completely describe
     * a Pattern. An empty pattern string results in an object tree with
     * only a Start node and a LastNode node.
    private Pattern(String p, int f) {

and compile method calls into that.

public static Pattern compile(String regex) {
        return new Pattern(regex, 0);

Since you are using == comparison which is for references it will not work

The only reason I can think of this behaviour is that the match flag will be defaulted to zero in the compile method which acts a factory method.

share|improve this answer
Well, I didn't say it hasn't a constructor. I just said it does not have a PUBLIC constructor :) –  Terry Li Dec 7 '12 at 7:33
The question is why is it so, especially when the compile method is this simple? –  Jan Dvorak Dec 7 '12 at 7:33
compile will behave as a factory method creating Pattern instances. The only reason I can think of is defaulting the match flag to zero in the compile method. –  Ajay George Dec 7 '12 at 7:35
@AjayGeorge sure, but Pattern does not need a factory ;-) –  Jan Dvorak Dec 7 '12 at 7:36
The defaulting behavior can just as easily happen in a constructor. –  Jan Dvorak Dec 7 '12 at 7:41

If you really want to take the deep dive, plunge into the archives of JSR 51.

Regular expressions have been introduced as part of JSR 51, that’s where you might still find the design decisions in their archives, http://jcp.org/en/jsr/detail?id=51

share|improve this answer
+1 good source! –  Terry Li Dec 7 '12 at 7:56

Your Answer


