Jens Schauder is software developer since 1997. He loves software development for the constant challenges and constantly changing environment. A great chance to learn and teach. He is also blogger, author of various articles and speaker at conferences. Jens is a DZone MVB and is not an employee of DZone and has posted 86 posts at DZone. You can read more from them at their website. View Full User Profile

Named Parameters in Java another Alternative

08.23.2012
| 7816 views |
  • submit to reddit

I wrote before about how you can emulate named parameters in a Java, either using methods or a builder. There is another approach, which already got mentioned in the comments.

On the usage side it looks like this:

  doSomething4(new ParameterObject() {{
        name = "Alfred E. Neumann";
        link = "http://blog.schauderhaft.de";
        ultimateAnswer = 42;
        tempFile = "c:\\temp\\x.txt";
        zip = 23;
    }});

I find this solution interesting, because it looks seriously weird. At least it did to me when I saw it for the first time, and also to many others who I observed when they encountered it for the first time. So what the heck are we exactly looking at?

        doSomething4(new ParameterObject() {
     //…
     });

Is an anonymous subclass of ParameterObject, which is defined like this

  class ParameterObject {
        protected String name;
        protected String link;
        protected int ultimateAnswer;
        protected String tempFile;
        protected int zip;
    }

so it is just a bunch of fields. The part that throws many people of is the nested set of {…} it is a java feature that doesn’t get much usage: an initializer. It is similar to a constructor, but can’t take any arguments. It gets executed before any constructor and in this case just sets the fields of the ParameterObject to the desired values.

Appart from the “WTF is this?” effect I don’t find much good things about this approach, especially because it is so confusing for many people. It saves a little typing on the implementor side of the interface I guess, but then you have this new WhatEverStuff() on the client side, which doesn’t help readability much.

Initializers and their siblings static intializers do belong in the toolbox of every java developer though.

 

 

 

Published at DZone with permission of Jens Schauder, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Lukas Eder replied on Fri, 2012/08/24 - 7:25am

This approach is also used in H2's database abstraction framework called JaQu:

http://www.h2database.com/html/jaqu.html 

A sample JaQu database query:

List<ProductGroup> list =
            db.from(p).
            groupBy(p.category).
            orderBy(1).
            select(new ProductGroup() {{
                category = p.category;
                productCount = count();
            }});

While it may look like a clever trick at first, the biggest drawbacks of this approach (apart from readability) are:

  • the fact that you will probably not be able to properly serialise / deserialise the anonymous type without much effort. 
  • the fact that this anonymous type is an inner class (as opposed to a static nested class). It will hold a reference to "this" in the context of the call site which can lead to unexpected results at the use site in terms of performance and/or memory management
  • the fact that every creation of such an anonymous class creates an additional burden for the class loader. If used heavily, this can have some impact on the PermGen space

 

Jonathan Fisher replied on Sun, 2012/08/26 - 11:26pm

I really think a propertly JavaDoc'd method and Eclipse eliminates the need for named parameters altogether. If you're not using either of those, you're 'banging the nail in when your head' rather than a hammer: http://www.infoq.com/presentations/Java-next

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.