It's not a secret anymore!
The moose likes Java in General and the fly likes Purpose of hiding default constructor Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Purpose of hiding default constructor" Watch "Purpose of hiding default constructor" New topic

Purpose of hiding default constructor

Johnny Grimes

Joined: Nov 18, 2007
Posts: 2
The Pattern and Matcher classes in in java.uti.regex package do not have public constructors. Instead, an object for those classes can be retrieved by invoking their static methods, Pattern.compile() and Matcher.matcher() respectively.
What is the reason? Why do they not have public constructor?
It is not clearly an implementation of Singleton Pattern which is characterized by getInstance() method.

Thanks in advance
Bear Bibeault
Author and ninkuma

Joined: Jan 10, 2002
Posts: 63862

It has nothing to do with Singletons. Look for information on the Factory pattern.

[Asking smart questions] [About Bear] [Books by Bear]
Jim Yingst

Joined: Jan 30, 2000
Posts: 18671
The Pattern and Matcher classes aren't singletons, but they are examples of the more general pattern of using a factory method. The singleton pattern is a special case of this, which is much overused and over-emphasized, and pretty much irrelevant here. Ignoring singletons, factory methods have a number of possible benefits in general, several of which are discussed in the linked article.

However, I don't think most of the points listed apply very much to Pattern. Instead I think that the main reason to use the pattern here is to allow for certain future optimizations - specifically, it's not always necessary to create a new Pattern object. A future implementation of Pattern could keep a cache of previously-created Pattern objects, and whenever a Pattern is requested that matches a previously-created Pattern, that existing object could be returned, rather than creating a new one. In certain situations this could result in substantial benefits to performance. Admittedly, this improvement is currently hypothetical - the current JDK does not do anything of the sort. But it could. If they had made the Pattern constructor public, then whenever someone called new Pattern(), there would have to be a new Pattern object created. Using a factory method instead allows more flexibility for future implementations, even if that flexibility is not utilized in current implementations.

Ultimately, while I think using a factory method here was a good idea, I think that they didn't do a good job of taking this thinking as far as they could have. The fact that Pattern has a private constructor prevents alternate implementations. Pattern should have been an interface, and another class (e.g. java.util.regex.Patterns) could have provided some standard implementations. The idea of caching Pattern instances is a good one - however in some cases it would create problems. If your program is regularly requesting completely new Pattern objects (which do not match any previous objects) then it may be a bad idea to try to keep all the previously-created Patterns in memory. So you don't want to force all users to use an implementation that caches Patterns in this way. Instead, better to have several implementations available, and let the user choose what works best for them.

As for the Matcher class, notice that contrary to what was said in the first post above, it doesn't have a private constructor - it has a package-elvel constructor. Nor is there a static matcher() method in Matcher - it's in Pattern. Because a Matcher really needs to be associated with a Pattern; there's no point at all in having a Matcher with no Pattern. So they put the factory method in that class - you need a Pattern before you can get a Matcher. Note that the method is not static - factory methods can be static or non-static; if they are not static then the objects they are attached to are called factories. This is a further specialization of the factory method pattern. In turn this can be further specialized to become the abstract factory pattern, which is not what we have here. But it is sufficiently well-known that it seemed worth mentioning for clarity. If you google "factory method pattern" you will probably find a fair amount of material which is specific to the abstract factory pattern, which is related, but is not strictly relevant here. So it's good to be aware that there are several levels of interrelated patterns here. Don't think that everything with the word "factory" in it is implemented the same way.
[ November 18, 2007: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Ernest Friedman-Hill
author and iconoclast

Joined: Jul 08, 2003
Posts: 24199

I was surprised, when I looked at the docs, to see that neither Pattern nor Matcher are abstract classes, and in fact, they're both final. I had assumed that they were using an abstract factory to select different implementations of these classes based on the actual regex being compiled. I guess the current implementation leaves that possibility open; because these classes have no public constructors, they could them both abstract and remove "final" and actually implement an abstract factory at some time in the future.

[Jess in Action][AskingGoodQuestions]
I agree. Here's the link:
subject: Purpose of hiding default constructor
It's not a secret anymore!