user8897013
user8897013

Reputation: 463

Is this syntax formatting normal for Java?

Came across this block of Java code from the Google Protocol Buffers Tutorial:

Person john =
  Person.newBuilder()
    .setId(1234)
    .setName("John Doe")
    .setEmail("[email protected]")
    .addPhones(
      Person.PhoneNumber.newBuilder()
        .setNumber("555-4321")
        .setType(Person.PhoneType.HOME))
    .build();

Been a while since I programmed in Java, but I'm not familiar with this form. I understand Person John = Person.newBuilder(), but .setId, .setName, etc. are not parameters to newBuilder, nor are they terminated between one another. Maybe its just the funny indentation. Also, is john.setId(1234) implied by .setId(1234)?

Upvotes: 1

Views: 67

Answers (2)

Bill K
Bill K

Reputation: 62769

That style of formatting is not completely normal in most code but when you are using a builder it is quite common since part of using a builder is the ability to chain calls to look like what you posted for readability.

It replaces a long parameter list which also tend to have strange formatting.

The dots indicate a call to the return value of the method on the previous line (Note that the line before each line starting with "." has no semi-colon). Every builder method returns "this" so that it can be chained in this way.

If one wasn't interested in readability your example could be re-written like this:

PersonBuilder johnBuilder = Person.newBuilder();
johnBuilder.setId(1234);
johnBuilder.setName("John Doe");
johnBuilder.setEmail("[email protected]");
PhoneBuilder phoneBuilder = Person.PhoneNumber.newBuilder();
phoneBuilder.setNumber("555-4321");
phoneBuilder.setType(Person.PhoneType.HOME);
johnBuilder.addPhones(phoneBuilder);
Person john = johnBuilder.build();

This pattern is driven by the desire for "Person" to be immutable--to be immutable all the parameters must be passed to the constructor making the constructor hard to understand. This breaks it down to show what is being passed for each line. The .build() line calls the Person constructor passing in all the values you put into the builder and returns an immutable Person, "john"

Without using the builder at all, it would look like this:

Person John = new Person (1234, "John Doe", "[email protected]", new Person.PhoneNumber("555-4321", Person.PhoneType.HOME));

or

Person John = new Person (
   1234, 
   "John Doe", 
   "[email protected]", 
   new Person.PhoneNumber(
       "555-4321", 
       Person.PhoneType.HOME
   )
);

If you look at your example you should find it more readable than this, and it will get much worse as the parameter list grows.

Upvotes: 2

Gerard van Helden
Gerard van Helden

Reputation: 1602

This is a pattern called "fluent interface" and is typically used in Builders to support a code flow like in your question.

The simple trick is returning "this" from the setter, so a new method call can be chained directly. It has nothing to do with syntax, in that respect, it's just another way of organising your code.

class Foo {
    public Foo() {}

    public Foo a () { /* do something and */ return this; }
    public Foo b () { /* do something else and */ return this; }
}

new Foo().a().b().a();

This is essentially the same pattern.

Upvotes: 2

Related Questions