Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Purpose of hiding default constructor

 
Johnny Grimes
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Marshal
Pie
Posts: 65228
95
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It has nothing to do with Singletons. Look for information on the Factory pattern.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ]
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic