Skip to content
Advertisement

Function chaining by returning parameter in Java

Seen regularly in the code and quite often used myself mostly to save myself a few lines.

class AAA {
   int val = 0;
}

AAA createSomething(){
   return new AAA();
}

AAA someProcessing(AAA aaa, int someOtherParameters ) {
   aaa.val += someOtherParameters;
   return aaa;
}

AAA someMoreProcessing(AAA aaa, int someOtherParameters ) {
   aaa.val ^= someOtherParameters;
   return aaa;
}

so that you can daisy chain the otherwise purely imperative methods in one-liners like

AAA calculate( int param1, int param2 ) {
   return someMoreProcessing(someProcessing(createSomething(),param1,param2);
}

as opposed to the classical way

AAA createSomething(){
   return new AAA();
}

void someProcessing(AAA aaa, int someOtherParameters ) {
   aaa.val += someOtherParameters;
}

void someMoreProcessing(AAA aaa, int someOtherParameters ) {
   aaa.val ^= someOtherParameters;
}

AAA calculate( int param1, int param2 ) {
   AAA aaa = createSomething();
   someProcessing(aaa,param1);
   someMoreProcessing(aaa,param2);
   return aaa;
}

There is of course some potential for abuse if you go over board with the daisy chaining like return a(b(c(d(),e(),f(g())), h(i()),j()));, but let’s assume you don’t.

On the one hand it will save you some typing and local variables, on the other hand you then always have to return the value from each function, which is additional lines of code and space on the stack. So the costs/benefits depends on how many and how big methods you have and how often you will use the daisy chaining.

So the question is three-fold.

  1. does this have a name ?
  2. is it considered bad practice in general ? ( i.e. because of the aforementioned abuse potential )
  3. what is the performance cost/benefit of it ? ( my guess is, it depends heavily on the circumstances, but then, under which circumstances it improves performance and under which it reduces it ? )

Advertisement

Answer

  1. Successive calls within one statement is known as call-chaining or method-chaining.

Returning the object reference to enable further calls effectively gives us method-cascading, a feature not otherwise built into the Java language.

When used strategically as part of a well-designed API, we call that a Fluent Interface.

  1. When designed thoughtfully, such an API design is a very good practice. For an example, see the java.time classes built into Java 8 and later.

As you mentioned, overuse or overwrought designs can ruin a good thing.

This is a situation where test-based design can be a big help. While designing an API, write tests using tools such as Jupiter in JUnit to exercise your methods. You want see to see if your fluent design succeeds in making practical use of call-chaining in semi-realistic use-cases. Try different approaches, adjust, and iterate until your design seems comfortable and practical.

  1. Regarding performance, I cannot say with certainty. I can tell you that the Java compiler, runtime optimizers (HotSpot or OpenJ9), and JVM are perhaps the most highly-tuned, highly-reviewed, and highly-tested software ever built for general purpose computing. The general rule is that writing simple straightforward code results in the most optimal runtime outcomes.

I doubt you would see any performance difference whether using call-chaining or not. Passing and returning an object reference is very cheap in Java.

Advertisement