Skip to content

Fluent API and annotations

A fluent API lets you call multiple methods in a row on the same object, usually by having each method return this (the same object).

Stage 1core1 min read

Fluent API (method chaining)

A fluent API lets you write related calls as one chain, so the code reads like a sentence. Each call returns an object, and the next call runs on it. A builder that can change usually returns this (itself). An immutable object, which cannot change, returns a new object at each step instead. For example, instead of:

builder.setCheese(true);
builder.setSide("fries");
builder.build();

you write:

builder.withCheese(true).withSide("fries").build();

Each method does its job (e.g. set a field) and returns this, so the next method runs on the same builder.

Example

build() ends the chain. It creates the final BurgerMeal from the values the builder collected.

public BurgerMealWithBuilder withCheese(boolean hasCheese) {
    this.hasCheese = hasCheese;
    return this;  // Return this so caller can chain: .withCheese(true).withSide("fries")
}

public BurgerMealWithBuilder withSide(String side) {
    this.side = side;
    return this;
}

public BurgerMeal build() {
    return new BurgerMeal(this);
}

Annotations

Annotations are labels you put on code, written with @. They give extra information to the compiler or other tools. They do not run like normal code.

  • @Override — says “this method replaces one from a parent class or interface.” The compiler checks that a matching method really exists there. If it does not (for example, you misspelled the name), you get an error. Use it on every override. Then, if the parent method is renamed, the compiler tells you instead of leaving an “orphan” method that nothing calls.
  • @SuppressWarnings("unused") — tells the compiler not to show one specific warning (e.g. unused variable) for that element. Use it sparingly, because warnings often point at real problems.

Example

@Override
public void pay(double amount) {
    System.out.println("Paying " + amount);
}
@SuppressWarnings("unused")
PaymentMethod pm = getSomePaymentMethod();  // We know we're not using pm here, suppress warning

Where you see it in this repo

  • BuilderPattern/After: withCheese(), withSide(), withDrinks() return this for fluent chaining; .withCheese(true).withSide("fries").withDrinks(...).build().
  • Every interface implementation and override: @Override on pay(), send(), clone(), read(), write(), etc.
  • LSP GoodCode Main: @SuppressWarnings("unused") where a variable is intentionally unused for demonstration.

In this topic

Done with this topic?

How well do you know it?

PreviousDependency injection