2

PrintStream's printf method has a return type of PrintStream and every time it is called it returns this object (the other print methods are void). So why is it designed like this? And for that matter if you have an object of any type that has a method that returns the object itself, what's the point then? You already had the object (this object specifically). So why return this object?

Michael
  • 41,989
  • 11
  • 82
  • 128

3 Answers3

4

It's called a fluent interface. It's designed so that you can chain together calls like so:

stream.printf("aaaa")
      .printf("bbbb")
      .printf("cccc");

Rather than doing:

stream.printf("aaaa");
stream.printf("bbbb");
stream.printf("cccc");

It's achieved by returning this at the end of the method:

class PrintStream extends FilterOutputStream implements Appendable, Closeable {
    //...

    public PrintStream printf(String var1, Object... var2) {
        return this.format(var1, var2);
    }

    public PrintStream format(String var1, Object... var2) {
        //...
        return this; // <-- here
    }
    //...
}

As to whether it's a good design pattern in this instance, I'd say not particularly. It's not offensively bad either.

Michael
  • 41,989
  • 11
  • 82
  • 128
3

The main purpose of returning the current object is to enable what's referred to as the fluent API, which makes call chaining possible:

object.method(arg).otherMethod(arg2).yetOtherMethod(arg3)

This style is more commonly used for builder/factory classes, but it's common to find it on other types of classes as well.

ernest_k
  • 44,416
  • 5
  • 53
  • 99
2

The print() methods that return void are legacy/original methods defined in the first released versions of PrintStream.

While PrintStream printf(String format, Object ... args) and PrintStream printf(Locale l, String format, Object ... args) were introduced later (more specifically in Java 5) in PrintStream.
Developers probably decided to introduce fluent methods to ease its use such as :

ps.print("Hello %s", oneString)
  .print("Hello %s", otherString);

As developers would not break the API of the class by refactoring the existing method (replacingvoid by fluent method), we get now a mix of them.
These new methods are fine but it results unfortunately to an inconsistent API : most of print methods return void and only two (that make probably part of the less common use) are fluent.

davidxxx
  • 125,838
  • 23
  • 214
  • 215