> For the complete documentation index, see [llms.txt](https://hanfak.gitbook.io/workspace/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hanfak.gitbook.io/workspace/languages/java/advanced/functional/immutability.md).

# Immutability

## Classes

* This depends on design decisions
* By using "final" in class signature, you cannot sub class it
* Make constructor private, use static factory methods
  * If constructor is non default, create a new default private constructor and throw an `AssertionException("should not instantiate this class")`. This avoids reflection being used to create an instance
* <https://stackoverflow.com/questions/12306651/why-would-one-declare-an-immutable-class-final-in-java>
* <https://www.infoworld.com/article/2073003/is-a-java-immutable-class-always-final-.html#:\\~:text=By%20declaring%20immutable%20classes%20final,immutability%2C%20are%20not%20a%20concern>.

## Fields

* Use of private final fields
* No setter methods
* Methods that change the state, should be avoided
  * instead return a new object with the new state in constructor
* But if you have access to the fields via a getter, then the object can stil be mutated internally
  * Thus getter has to either return a copy (deep or shallow copy depending on the object graph)

## Arguments

* Either by convention (to avoid cluttering code), keep all method parameters final.
* Can use the keyword "final" in method parameters signature
* Even better would be to make any argument passed into a method be immutable
  * This can be hard, and also lead to trade off in creating less readable code

## Variables

### Assign once

* Bad

```java
Thing thing;
if (nextToken == MakeIt) {
  thing = makeTheThing();
} else {
  thing = new SpecialThing(dependencies);
}
thing.doSomethingUseful();
```

* Better, use ternary and assign to variable

```java
final var thing =
  nextToken == MakeIt ? makeTheThing(): new SpecialThing(dependencies);
thing.doSomething();
```

* Better, wrap it in a function

```java
final var thing = aThingFor(nextToken);
thing.doSomethingUseful();

private Thing aThingFor(Token aToken) {
  return aToken == MakeIt ? makeTheThing() : new SpecialThing(dependencies);
}
```

* If used once, can inline, and get rid of variable (as long naming of method is good)

```java
aThingFor(nextToken).doSomethingUseful();

private Thing aThingFor(Token aToken) {
  return aToken == MakeIt ? makeTheThing() : new SpecialThing(dependencies);
}
```

* For complex conditions, like switches, can wrap it up in a method

### Localise scope

* Distance between assigning variable and use is far apart

```java
var thing = Thing.DEFAULT;
// lots of code to figure out nextToken
if (nextToken == MakeIt) {
  thing = makeTheThing();
}
thing.doSomethingUseful();
```

* Better, use private method

```java
final var thing = theNextThingFrom(aStream);

private Thing theNextThingFrom(Stream aStream) {
// lots of code to figure out nextToken
  if (nextToken == MakeIt) {
    return makeTheThing();
  }
  return Thing.DEFAULT;
}
```

* Better use stream

```java
final var thing = nextTokenFrom(aStream)
                    .filter(t -> t == MakeIt)
                    .findFirst()
                    .map(t -> makeTheThing())
                    .orElse(Thing.DEFAULT);
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hanfak.gitbook.io/workspace/languages/java/advanced/functional/immutability.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
