The Artima Developer Community
Sponsored Link

Java Buzz Forum
Are constructors useless?

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Daniel Bonniot

Posts: 8
Nickname: dbr
Registered: Oct, 2004

Daniel Bonniot is the designer of the Nice programming language
Are constructors useless? Posted: Dec 31, 2004 1:38 PM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Daniel Bonniot.
Original Post: Are constructors useless?
Feed Title: Daniel Bonniot's Weblog
Feed URL: http://www.jroller.com/dbr/feed/entries/rss?cat=%2FNice
Feed Description: Design ideas around the Nice programming language
Latest Java Buzz Posts
Latest Java Buzz Posts by Daniel Bonniot
Latest Posts From Daniel Bonniot's Weblog

Advertisement

I know what you must think: this guy just started blogging, and he's already turned crazy. We all know constructors are very useful: they set up the internal state of a new instance and perform any action that might be needed upon construction. Without them, we would be back to the dark age of pre-OO-ness, using records and manually setting their fields when creating a new record. Right?

OK, maybe I was a little bold (but titles have to be catchy, don't they?). I have had this intuition for some time that many constructors are just redundant. They take a certain number of arguments, pass the first half to the super constructor, and use the second half to set the fields of the current class. How boring!

Here's an example from Eclipse, in class org.eclipse.update.internal.mirror.MirrorCommand:

public class MirrorCommand extends ScriptedCommand {
 
        private String featureId;
        private String featureVersion;
        private String fromSiteUrl;
        private String toSiteDir;
        private String mirrorURL;
        private MirrorSite mirrorSite;
 
        public MirrorCommand(
                String featureId,
                String featureVersion,
                String fromSiteUrl,
                String toSiteDir,
                String mirrorUrl) {
                this.featureId = featureId;
                this.featureVersion = featureVersion;
                this.fromSiteUrl = fromSiteUrl;
                this.toSiteDir = toSiteDir;
                this.mirrorURL = mirrorUrl;
        }

    ....

}

See what I mean? I'm sure you have seen a gazillion similar constructors.

So I was going to rant about those. But then I thought: is it just me? Do I really know how much this happens in practice? What about getting some hard numbers? First, we'll need a large enough Java program, with source code publicly available. I settled on Eclipse, as it's quite well known in the community. I downloaded the latest version, 3.0M7, in source form. Now, that's an awful lot of code (over 2M lines), I'm not going to look through it manually, so I'll need an automated way to discover which constructors are "trivial". No problem: let's just take some available grammar that parses Java source code, and add a special case for trivial constructors. By counting how many times this one is used, and how many times the general case of constructors is needed, we can get the ratio.

I used the JavaCC parser generator, as I happen to be familiar with the tool, and I know there are Java grammars available for it. The definition of trivial constructors is, well, trivial: a constructor whose body matches: [ ExplicitConstructorInvocation() ] ( [ "this" "." ] "=" ";" )*. That is, an optional call to another constructor, followed by simple assignments of a variable to another. No method call, no arithmetics.

Now the grand moment of result was approching. Are there many constructors that fit in this simplistic form? What would you say, from the top of your head? Come on, take a guess!

Well, even with some a priori, I was surprised by the results. Out of the 9033 constructors in Eclipse, 5003 are in this trivial form. That's more than 55%! To make sure that this result was not specific to eclipse, I downloaded the source code of Tomcat 5. Results: 64% of constructors are trivial! GNU Classpath: 72%!

These scores of dumb constructors are not only a pain to write. After all, editors could help with that. For instance, eclipse proposes you to "Generate constructor using fields", but you still need to choose that from the menu, select which fields to initialize, validate. And fill in the javadoc comment. Having all these dumb constructors also means that each time you change a base constructor, you have to update all the constructors in child classes that call the base constructor. And of course, all this trivial code does not help making your classes more readable and maintainable.

OK, the point is made, there seems to be a lot of wasted effort and obfuscation, but what can be done differently? Well, since this situation is so common, shouldn't we let the compiler do it for us? That is, for every class, a default constructor should be created that performs the job of initializing the fields of the class and calling a parent constructor. If there are several parent constructors, one such default constructor should be generated for each of them.

But wait! You'll say: "There is a problem! In what order do the fields appear in the default constructor arguments? Sure, we could keep the order in which they are declared in the class, but that would mean that changing the order of declaration will change the constructor. That does not sound right." That's a good question! The answer is: in no particular order. What would make most sense was if we could require that calls to this constructor are made by specifying which values goes in which field. That's what named (or keyword) arguments are for. Going back to our example, we could omit the constructor, and create a new instance with:

  new MirrorCommand(featureId: "foo", featureVersion: "1.0", ...);

One additional benefit is that the constructor call is more readable, since you don't need to know by heart the order and name of all arguments to get an idea of what it does.

When fields have initializers, those become default values of the corresponding arguments on the default constructor. So it's possible to omit them in the constructor call, but you can specify some if you want a different value for some field.

The bad news is: implicit constructors, named arguments, this does not seem to be standard Java. Nor will it be anytime soon. None of this is in 1.5, nor in preparation. Java is moving very slowly (more than 7 years from the Pizza paper to generics in Java 1.5), so don't hold your breath... The good news is: you can get all these features, and much more, if you decide to use the Nice language. It compiles to Java bytecode, knows how to reuse existing Java libraries, and in general integrates well with Java. Nice has had these default constructors for a long time. Recently, with version 0.9.6, it got the ability to define custom constructors for those 45%, 36%, or 28% of cases where the default constructor is not sufficient. Actually, those numbers are probably much lower, because in many cases you can get by with a default constructor together with an instance initilizer (it just seemed difficult to count those cases). Using an initializer, you can leave the standard job to the default constructor, and add specific code to be executed after initialization. Still, it's useful to be able to write a custom constructor. For instance when you want to allow some alternate list of arguments for construction, from which the values of the fields can be computed. Moreover, custom constructors are also useful if you decide to change the internal representation of the class, but want to keep its public API intact.

Further info and examples are available in the Constructors section of Nice's user manual.

Nice is developed under an open-source model, so comments and contributions are particularly welcome!

Read: Are constructors useless?

Topic: Project blogs Previous Topic   Next Topic Topic: [Dec 17, 2004 02:38 PST] 10 Links

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use