Patrick Logan points to two interesting articles on new(); (in the context of Java). The first one is new considered harmful
- Memory allocation
Because memory allocation is new's primary function, it is hard to see how allocating memory from the heap could be a problem. But sometimes you want to allocate memory from somewhere other than the heap, and at other times you don't want to allocate memory at all. In other words, you may want an object, but you may not want to create one, at least not here, not now.
Now, in a language like Smalltalk, this isn't necessarily a problem - you can create your own version of #new and have it do what you want (create a new instance, manage some pool of instances by issuing one, return a singleton... you get the idea). As to where in memory the object is created - well, I figure the GC sub-system is going to do a better job with that than I am, so if I get a newly allocated object, I'm happy to let the system handle it. However - I can manage what #new does. The author of this paper goes through a number of examples of the issues in Java; it's worth reading. My little discussion of #new in Smalltalk gets into his second concern: polymorphism:
Turning to the second problem: new is famously nonpolymorphic. When I write new Rectangle(), I always get a Rectangle, never anything else, and in particular never a subclass of Rectangle. Much of the time this is what I want, but sometimes it isn't; for example:
A framework where I request an implementation by name or other attribute, and am given an instance of the appropriate class. Some of the classes in the java.security package, like Signature, work this way. Or imagine a data structure wizard that lets a client specify the desired properties of a data structure (for example, constant average-time access, no duplicates, ordering not required) and returns an implementation satisfying the criteria (HashSet, for instance).
Well, #new in Smalltalk is, of course, polymorphic. A good example of Factory usage in VisualWorks is the class SocketAccessor - you send instance creation messages to that class, but you actually get a platform specific subclass. It's not that you can't do this in Java; it's that you can't do it in the context of new(). What this does is add a layer of cruft, whereby you have to remember "oh yeah, I can't do that here...". To quote another section and reveal another issue:
The problem with static factory methods is that they are static; strictly speaking, a call to one is not polymorphic. That is, when you call Signature.getInstance you are always invoking the same code. Although its strategy for returning an appropriate subclass may be clever and complex, there is no way to use a different strategy.
The obvious antidote - indeed, the only other possibility - is a nonstatic factory method. In other words, you call a method on an object, and you get back an object (possibly a new one). Since instance (that is, nonstatic) method calls can be polymorphic, creation can be as well. There are a variety of ways in which this basic mechanism can be exploited.
Here the problem is that in Java, classes aren't actually objects - you can't add class methods in the same sense that you can in languages like Smalltalk. Again, this adds a layer of cruft that developers have to work around. A lot of what's problematic in java could be fixed by making classes into actual objects, and getting rid of keywords and adding methods (new() as opposed to #new). That's not going to happen anytime soon, so Java developers will just have to keep climbing the same piles of cruft over and over again...
Now, compare that with this discussion over on the Squeak-dev list.