Search code examples
javalanguage-designlanguage-featuresjava-7

Chained invocation in Java 7?


I was just reading a Java 7 preview presentation (pdf) and there was a slide on Chained Invocation. Here is the example used in the slide:

// Construction with setters
DrinkBuilder margarita = new DrinkBuilder();
margarita.add("tequila");
margarita.add("orange liqueur");
margarita.add("lime juice");
margarita.withRocks();
margarita.withSalt();
Drink drink = margarita.drink();

// Construction with chained invocation
Drink margarita = new DrinkBuilder()
    .add("tequila")
    .add("orange liqueur")
    .add("lime juice")
    .withRocks()
    .withSalt()
    .drink();

And I have mixed feelings about this. One shouldn't chain too many method invocations into one statement. On the other hand, writing margarita.this() and margarita.that() isn't too convenient either.

Now, I am coming to Java from Delphi world. And in Delphi there is the with language construct. This is cherished by a few and loathed by many (or is it the other way around?). I find with to be more elegant than the idea of chained invocation (which I believe works on the basis of void method returning reference to object on which it has been invoked - and this is the part I don't like, as void should return nothing).

I would appreciate the with language feature being adopted by Java, so the example code could be written like so:

Drink margarita = null;
with (new DrinkBuilder()) {
    add("tequila");
    add("orange liqueur");
    add("lime juice");
    withRocks();
    withSalt();
    margarita = drink();
}

Am I the only one who would prefer this solution to the chained invocation? Anyone else feels that with could be a useful extension to Java language? (Reminds me of someone's question about the need of "Java++"...)


Solution

  • the with statement can be translated in Java using anonymous classes with initializer:

    Drink margarita = new DrinkBuilder() {{
        add(“tequila”);
        add(“orange liqueur”);
        add(“lime juice”);
        withRocks();
        withSalt();
    }}.drink();
    

    the downsides of using this idiom are well documented here.

    Chained Invocation is an alias for Method Chaining. That is well known idiom and works with any version of Java:

    class Chained {
    
        public Chained withFoo() { 
            // ...
            return this;
        }
    
        public Chained withBar() { 
            // ...
            return this;
        }
    }    
    

    a proposal for JDK 7 is allowing of chaining method also for void return type:

    class ChainedJava7 {
    
        public void withFoo() { 
            // ...
        }
    
        public void withBar() { 
            // ...
        }
    }