# From C++ — building the same `Tariff` both ways

The parking lot's tariff is three rates that never change after construction. You have written
this class hundreds of times. Every mechanism you would reach for is missing here, and the
replacements are not one-to-one.

## The immutable value

**C++ — an initialiser list, and `const` members**

```cpp
class Tariff {
public:
    Tariff(long motorbikeMinor, long carMinor, long truckMinor)
        : motorbikeMinor_(motorbikeMinor),   // const members are initialised here,
          carMinor_(carMinor),               // before the body runs, and only here
          truckMinor_(truckMinor) {}

private:
    const long motorbikeMinor_;
    const long carMinor_;
    const long truckMinor_;
};
```

**Java — the body is the only place**

```java
public final class Tariff {

    private final long motorbikeMinor;
    private final long carMinor;
    private final long truckMinor;

    private Tariff(long motorbikeMinor, long carMinor, long truckMinor) {
        this.motorbikeMinor = motorbikeMinor;
        this.carMinor = carMinor;
        this.truckMinor = truckMinor;
    }
}
```

There is no syntax between the parameter list and the `{`. A `final` field is assigned by an
ordinary statement, and `javac` runs a definite-assignment analysis over every path through
the constructor to prove each one is assigned exactly once.

Two errors come out of that analysis, and they are the two you will meet first.

**Miss a path.** Add a guard that returns early:

```java
    private Tariff(long motorbikeMinor, long carMinor, long truckMinor) {
        this.motorbikeMinor = motorbikeMinor;
        this.carMinor = carMinor;
        if (truckMinor < 0) {
            return;
        }
        this.truckMinor = truckMinor;
    }
```

```
Tariff.java:11: error: variable truckMinor might not have been initialized
            return;
            ^
1 error
```

Note where the caret lands. Not on the field, and not on the assignment. It lands on the
`return`, because that is the statement that reaches the end of the constructor with the field
still unset. An empty constructor body gets the same message pointed at the closing brace.

**Assign twice.** Clamp a bad rate instead of returning:

```java
        this.carMinor = carMinor;
        if (carMinor < 0) {
            this.carMinor = 0;
        }
```

```
T2.java:8: error: variable carMinor might already have been assigned
            this.carMinor = 0;
                ^
1 error
```

The related message, and the one the spec for this lesson names, appears when you assign a
`final` field from anywhere that is not a constructor:

```java
    public void raiseTo(long newRate) {
        this.carMinor = newRate;
    }
```

```
T5.java:10: error: cannot assign a value to final variable carMinor
        this.carMinor = newRate;
            ^
1 error
```

Same rule, three messages. `might not have been initialized` means a path assigned it zero
times, `might already have been assigned` means a path could assign it twice, and
`cannot assign a value to final variable` means the code is not in a constructor at all.

**One more that C++ does not have an equivalent for.** Building a list in a loop:

```java
    public T7(int n) {
        for (int i = 1; i <= n; i++) {
            this.spotIds = List.of("S" + i);
        }
    }
```

```
T7.java:7: error: variable spotIds might be assigned in loop
            this.spotIds = List.of("S" + i);
                ^
T7.java:9: error: variable spotIds might not have been initialized
    }
    ^
2 errors
```

`n` could be 0, and it could be 5, so `javac` refuses both ways at once. The fix is the shape
`SpotGrid` uses in the reference solution: accumulate into a local, assign the field once
afterwards. `SpotNumbering` in `worked/` does the same.

## `final` is not `const`, and here it is the stronger one

The word looks like a translation and it is not. `const` in C++ mostly attaches to the
*access path*: `const Tariff&`, `long rate() const`. `final` attaches to the *declaration*.

```cpp
void audit(const Tariff& t);      // this function cannot mutate t
```

```java
void audit(Tariff t)              // says nothing about t at all
```

Java has no way to write that parameter. `final Tariff t` stops you reassigning the local `t`
and permits every mutation of the object. So a Java method receiving an object has no
compiler-checked promise about it. That sounds like a loss, and it is why the convention went
the other way: **immutability becomes a property of the class, not of the reference.**

That is the direction where `final` wins. A `const Tariff&` guarantees nothing about what
other holders do, because a non-const alias can exist elsewhere and mutate under you. A
`Tariff` whose fields are all `final`, of immutable types, in a `final` class, cannot be
mutated by anyone. Every holder gets the guarantee, so:

- `Tariff.standard()` returns one shared instance rather than a copy, and `Main` prints
  `standard() twice, same object? true`
- No defensive copy at any boundary, and none of the `copy` constructors C++ needs
- Safe to publish to another thread with no lock, which is J12

The price is stated plainly: no partial immutability. There is no `const` overload, so a class
is immutable or it is not. A mutable class you wanted to lend out read-only needs an interface
carrying only the read methods.

## No default arguments

**C++ — one constructor covers four call shapes**

```cpp
class LotConfig {
public:
    explicit LotConfig(int standardSpots,
                       Tariff tariff = Tariff::standard(),
                       int graceMinutes = 0,
                       int freeHours = 0);
};
```

**Java — a second constructor that delegates**

```java
    public LotConfig(int standardSpots) {
        this(standardSpots, Tariff.standard(), 0, 0);
    }

    public LotConfig(int standardSpots, Tariff tariff, int graceMinutes, int freeHours) {
        // validation, then the only four field assignments in the class
    }
```

`this(...)` is C++'s delegating constructor with the same restriction: it has to come first.

```
T3.java:17: error: call to this must be first statement in constructor
        this(a, b);
            ^
1 error
```

One canonical constructor validates and assigns; every other constructor delegates to it. That
is the whole pattern, and it holds until two defaults have the same type.

## Where telescoping dies, and why a factory has a name

Two new requirements arrive. A grace period in minutes, and curveball 02's free first hours.
Both want a two-argument form:

```java
    public LotConfig(int standardSpots, int graceMinutes) { … }
    public LotConfig(int standardSpots, int freeHours)    { … }
```

```
T4.java:10: error: constructor T4(long,long,long) is already defined in class T4
    public T4(long motorbikeRupees, long carRupees, long truckRupees) {
           ^
1 error
```

A constructor's name is the class name, so its parameter types are its entire identity. Two
meanings with one shape cannot coexist. C++ has the same rule and you rarely feel it, because
default arguments meant you only ever wrote one constructor.

Static factories have names:

```java
    public static LotConfig withGraceMinutes(int standardSpots, int graceMinutes) { … }
    public static LotConfig withFreeHours(int standardSpots, int freeHours)       { … }
```

Both compile, both read correctly at the call site, and `LotConfig.withFreeHours(10, 1)` cannot
be confused with the other one by a reader or by overload resolution. `Tariff` in `worked/`
carries the same pair: `perStartedHourMinor(1000, 2000, 4000)` and
`perStartedHourRupees(10, 20, 40)`, three `long`s each.

**This is the reason a C++ developer has never needed a static factory.** The other three
reasons are real but weaker, and you have seen them all in C++ as free functions:

| Reason | What it buys | C++ equivalent you already use |
|---|---|---|
| It has a name | Two factories, one parameter list | free function `makeX` |
| It can validate first | Throws before an object exists, so no half-built state | factory function returning `optional` |
| It can return a cached instance | `Tariff.standard()` hands out one object | a `static const` singleton |
| It can return a subtype | The caller sees the interface, never the class | factory returning `unique_ptr<Base>` |

### And the threshold, because a factory is not free

Use `new` when the class has one way in and the constructor cannot fail. `new Vehicle("KA01AB1234", CAR)`
is honest; `Vehicle.of(...)` adds a name to read and a layer to step through for nothing.

Reach for a static factory when one of these is true:

1. Two ways in share a parameter list. This one is forced, not a preference
2. The class is immutable and instances are worth sharing, like `Tariff.standard()`
3. Construction can fail on its arguments and you want the failure before an object exists
4. Callers should depend on an interface, which is exactly `Entry.create()` below

If none of the four holds, a public constructor is the smaller thing to read. STANDARD v1.0's
D3 level 3 anchor reads *"the seam set is minimal"*, and the tag for failing it is
`over-engineered`. A factory nobody needed costs you score rather than earning it.

## `Entry.create()`, the one static factory you will type in every attempt

This is real, and it is `corpus/parking-lot/contract/Entry.java`:

```java
public final class Entry {

    /** A lot with 10 standard spots on one floor. Return your implementation. */
    public static ParkingLotApi create() {
        return new ParkingLot(10);   // ← EDIT THIS LINE: your class, your constructor
    }

    private Entry() {}
}
```

Every hidden test calls `Entry.create()` and nothing else of yours. Reason 4 in the table is
the whole design: the return type is the interface, so the grader compiles against
`ParkingLotApi` while the body names `ParkingLot` and your constructor. A constructor could not
do this job, because `new` has to name a concrete class and that name would have to be one the
tests knew.

Which makes the last line worth reading too. `private Entry() {}` on a class of static members
is the Java idiom for "not instantiable". Leave it out and Java supplies a public no-argument
constructor, so `new Entry()` compiles and means nothing. C++ gives you a free namespace for
this; Java has no free functions, so the holder is a class you have to close off by hand.

`Entry.create()` also shows why the convenience constructor earns its place. The reference
`ParkingLot` has a canonical `ParkingLot(SpotGrid, SpotAllocator, PricingPolicy)` and a
`ParkingLot(int)` that delegates to it with `this(new SpotGrid(n), new FirstFitAllocator(), new FlatHourlyPricing())`.
That is what keeps this line one line.

## Initialisation order, and the trap with no C++ analogue

**C++ — a virtual call from a constructor uses the base's version**

```cpp
class SpotNumbering {
public:
    explicit SpotNumbering(int count) {
        for (int i = 1; i <= count; ++i) ids_.push_back(label(i));  // SpotNumbering::label
    }
    virtual std::string label(int n) const { return "S" + std::to_string(n); }

private:
    std::vector<std::string> ids_;
};
```

During a C++ base constructor the object's dynamic type *is* the base. The vtable pointer is
updated as each stage completes, so `label(i)` resolves to `SpotNumbering::label` even when the
object being built is a `PrefixedNumbering`. Declare `label` pure virtual instead and the call
is undefined behaviour, which libstdc++ turns into a run-time abort reading
`pure virtual method called`.

**Java — the subclass override runs, on an object with no fields yet**

```java
    protected SpotNumbering(int count) {
        List<String> ids = new ArrayList<>(count);
        for (int i = 1; i <= count; i++) {
            ids.add(label(i));          // PrefixedNumbering.label, every time
        }
        this.spotIds = List.copyOf(ids);
    }
```

There is one vtable and it is complete from the first instruction. `label(i)` dispatches to the
override immediately, and the override reads `prefix`, which `PrefixedNumbering`'s constructor
has not reached yet. Real output from `worked/`:

```
new PrefixedNumbering(3, "S").spotIds() -> [null1, null2, null3]
```

No exception. No warning from plain `javac`. Wrong spot ids, in production.

The same bug one method call further along does throw, because a reference field defaults to
`null` rather than to a sensible-looking empty value:

```
new PaddedNumbering(3, "a") threw java.lang.NullPointerException
  message: Cannot invoke "String.toUpperCase()" because "this.prefix" is null
  top frames:
    at PaddedNumbering.label(SpotNumbering.java:67)
    at SpotNumbering.<init>(SpotNumbering.java:25)
    at PaddedNumbering.<init>(SpotNumbering.java:61)
```

Read the three frames bottom to top and the mechanism is stated for you. `PaddedNumbering`'s
constructor called `SpotNumbering`'s, which called `PaddedNumbering.label`. Java 21's helpful
message names the field, `this.prefix`, which is the fastest diagnosis you will get all week.

The order the trace in `worked/` prints:

```
     1  label(1) runs inside SpotNumbering's constructor; prefix is null
     2  field initialiser, declared first
     3  instance initialiser block, declared between the two fields
     4  field initialiser, declared second
     5  constructor body: the first statement that can see prefix=S
```

So: `super()` completes, then field initialisers and instance initialiser blocks run
interleaved in declaration order, then your constructor body. Field initialisers are not
special. They are constructor statements that `javac` moves for you, which is why an
initialiser referring to a field declared below it fails with `illegal forward reference`.

### The one flag that catches this

`javac` has a lint category for it, off by default:

```
> javac -Xlint:this-escape -d out lessons/J4/worked/src/*.java
lessons\J4\worked\src\SpotNumbering.java:25: warning: [this-escape] possible 'this' escape before subclass is fully initialized
            ids.add(label(i));
                         ^
1 warning
```

One warning, on the exact line. Plain `javac` on the same sources prints nothing and exits 0.
It fires on any constructor of an extensible class that calls an overridable method, so it
finds this class of bug before a null does.

## The delta table

| C++ | Java |
|---|---|
| member initialiser list | assignments in the constructor body, nothing before `{` |
| `const` member | `final` field, assigned exactly once on every path |
| `const T&` parameter | no equivalent; make the class immutable instead |
| default arguments | a second constructor delegating with `this(...)` |
| overload on default-argument count | static factories, because they have names |
| copy constructor | usually nothing to write; `final` fields make the object shareable |
| `explicit` | no equivalent; Java has no converting constructors |
| a virtual call in a constructor runs the base version | it runs the **subclass override**, on null fields |
| compiler warns about a pure virtual call in a constructor | silent unless you pass `-Xlint:this-escape` |
| free `makeThing()` in a namespace | `static` factory on the class; there are no free functions |
| private constructor to block construction | same, plus `private Entry() {}` to block instantiation |

## The habit that will cost you time today

Writing a `validate()` or `init()` method and calling it from the constructor. In C++ that is
ordinary. In Java, if the class can be extended and the method can be overridden, you have
built the trap above.

Two fixes, and they are not equivalent. Make the helper `static`, so it cannot read a field at
all, and pass its result to the field or to `super(...)`. Or make the class `final` and the
helper `private`, so no override can exist. `FixedNumbering` in `faded/` takes the first route,
and if you try to route an *instance* method through `super(...)` the compiler stops you:

```
T8.java:11: error: cannot reference this before supertype constructor has been called
        super(labels(count, prefix));
              ^
1 error
```
