or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation-generation.mdbuilders.mdextensions.mdindex.mdmemoization.mdpretty-strings.mdserialization.mdstandalone-builders.mdtagged-unions.mdvalue-classes.md

builders.mddocs/

0

# Builder Pattern

1

2

AutoValue can generate builder classes that provide a fluent API for constructing value objects, especially useful for classes with many properties or optional fields.

3

4

## Basic Builder

5

6

```java { .api }

7

@AutoValue

8

public abstract class Person {

9

public abstract String name();

10

public abstract int age();

11

public abstract Optional<String> email();

12

13

public static Builder builder() {

14

return new AutoValue_Person.Builder();

15

}

16

17

@AutoValue.Builder

18

public abstract static class Builder {

19

public abstract Builder name(String name);

20

public abstract Builder age(int age);

21

public abstract Builder email(String email);

22

public abstract Person build();

23

}

24

}

25

```

26

27

## Usage Example

28

29

```java

30

Person person = Person.builder()

31

.name("Alice")

32

.age(30)

33

.email("alice@example.com")

34

.build();

35

36

// Optional properties can be omitted

37

Person personWithoutEmail = Person.builder()

38

.name("Bob")

39

.age(25)

40

.build();

41

```

42

43

## Builder with Defaults

44

45

Set default values in the builder factory method:

46

47

```java { .api }

48

@AutoValue

49

public abstract class Configuration {

50

public abstract String host();

51

public abstract int port();

52

public abstract boolean ssl();

53

public abstract int timeoutMs();

54

55

public static Builder builder() {

56

return new AutoValue_Configuration.Builder()

57

.host("localhost")

58

.port(8080)

59

.ssl(false)

60

.timeoutMs(5000);

61

}

62

63

@AutoValue.Builder

64

public abstract static class Builder {

65

public abstract Builder host(String host);

66

public abstract Builder port(int port);

67

public abstract Builder ssl(boolean ssl);

68

public abstract Builder timeoutMs(int timeoutMs);

69

public abstract Configuration build();

70

}

71

}

72

```

73

74

Usage with defaults:

75

76

```java

77

Configuration defaultConfig = Configuration.builder().build();

78

// host=localhost, port=8080, ssl=false, timeoutMs=5000

79

80

Configuration customConfig = Configuration.builder()

81

.host("api.example.com")

82

.ssl(true)

83

.build();

84

// host=api.example.com, port=8080, ssl=true, timeoutMs=5000

85

```

86

87

## Builder with Collections

88

89

Builders provide convenience methods for adding to collections:

90

91

```java { .api }

92

@AutoValue

93

public abstract class Team {

94

public abstract String name();

95

public abstract ImmutableList<String> members();

96

public abstract ImmutableSet<String> skills();

97

98

public static Builder builder() {

99

return new AutoValue_Team.Builder();

100

}

101

102

@AutoValue.Builder

103

public abstract static class Builder {

104

public abstract Builder name(String name);

105

106

// Collection setters

107

public abstract Builder members(Iterable<String> members);

108

public abstract Builder skills(Iterable<String> skills);

109

110

// Individual item adders (generated automatically)

111

public abstract Builder addMember(String member);

112

public abstract Builder addSkill(String skill);

113

114

// Multiple item adders (generated automatically)

115

public abstract Builder addAllMembers(Iterable<String> members);

116

public abstract Builder addAllSkills(Iterable<String> skills);

117

118

public abstract Team build();

119

}

120

}

121

```

122

123

Usage:

124

125

```java

126

Team team = Team.builder()

127

.name("Backend Team")

128

.addMember("Alice")

129

.addMember("Bob")

130

.addAllMembers(Arrays.asList("Charlie", "Diana"))

131

.addSkill("Java")

132

.addAllSkills(Arrays.asList("Spring", "PostgreSQL"))

133

.build();

134

```

135

136

## toBuilder() Method

137

138

Generate a builder from an existing instance:

139

140

```java { .api }

141

@AutoValue

142

public abstract class Person {

143

public abstract String name();

144

public abstract int age();

145

public abstract Optional<String> email();

146

147

// toBuilder method

148

public abstract Builder toBuilder();

149

150

public static Builder builder() {

151

return new AutoValue_Person.Builder();

152

}

153

154

@AutoValue.Builder

155

public abstract static class Builder {

156

public abstract Builder name(String name);

157

public abstract Builder age(int age);

158

public abstract Builder email(String email);

159

public abstract Person build();

160

}

161

}

162

```

163

164

Usage:

165

166

```java

167

Person original = Person.builder()

168

.name("Alice")

169

.age(30)

170

.build();

171

172

Person updated = original.toBuilder()

173

.age(31)

174

.email("alice@example.com")

175

.build();

176

```

177

178

## Property Builders for Nested Objects

179

180

Build nested objects directly in the builder:

181

182

```java { .api }

183

@AutoValue

184

public abstract class Address {

185

public abstract String street();

186

public abstract String city();

187

188

public static Builder builder() {

189

return new AutoValue_Address.Builder();

190

}

191

192

@AutoValue.Builder

193

public abstract static class Builder {

194

public abstract Builder street(String street);

195

public abstract Builder city(String city);

196

public abstract Address build();

197

}

198

}

199

200

@AutoValue

201

public abstract class Person {

202

public abstract String name();

203

public abstract Address address();

204

205

public static Builder builder() {

206

return new AutoValue_Person.Builder();

207

}

208

209

@AutoValue.Builder

210

public abstract static class Builder {

211

public abstract Builder name(String name);

212

public abstract Builder address(Address address);

213

214

// Property builder for nested object

215

public abstract Address.Builder addressBuilder();

216

217

public abstract Person build();

218

}

219

}

220

```

221

222

Usage:

223

224

```java

225

Person person = Person.builder()

226

.name("Alice")

227

.addressBuilder()

228

.street("123 Main St")

229

.city("Springfield")

230

.and() // Returns to parent builder

231

.build();

232

233

// Or build separately

234

Address address = Address.builder()

235

.street("456 Oak Ave")

236

.city("Springfield")

237

.build();

238

239

Person person2 = Person.builder()

240

.name("Bob")

241

.address(address)

242

.build();

243

```

244

245

## Builder Validation

246

247

Add validation to the build() method:

248

249

```java { .api }

250

@AutoValue

251

public abstract class ValidatedPerson {

252

public abstract String name();

253

public abstract int age();

254

public abstract String email();

255

256

public static Builder builder() {

257

return new AutoValue_ValidatedPerson.Builder();

258

}

259

260

@AutoValue.Builder

261

public abstract static class Builder {

262

public abstract Builder name(String name);

263

public abstract Builder age(int age);

264

public abstract Builder email(String email);

265

266

abstract ValidatedPerson autoBuild(); // Package-private build method

267

268

public ValidatedPerson build() {

269

ValidatedPerson person = autoBuild();

270

checkArgument(!person.name().isEmpty(), "Name cannot be empty");

271

checkArgument(person.age() >= 0, "Age must be non-negative");

272

checkArgument(person.email().contains("@"), "Invalid email format");

273

return person;

274

}

275

276

private static void checkArgument(boolean condition, String message) {

277

if (!condition) {

278

throw new IllegalArgumentException(message);

279

}

280

}

281

}

282

}

283

```

284

285

## Optional Properties with Builders

286

287

Handle optional properties elegantly:

288

289

```java { .api }

290

@AutoValue

291

public abstract class Product {

292

public abstract String name();

293

public abstract double price();

294

public abstract Optional<String> description();

295

public abstract Optional<String> category();

296

297

public static Builder builder() {

298

return new AutoValue_Product.Builder();

299

}

300

301

@AutoValue.Builder

302

public abstract static class Builder {

303

public abstract Builder name(String name);

304

public abstract Builder price(double price);

305

public abstract Builder description(String description);

306

public abstract Builder category(String category);

307

308

// Optional overloads for convenience

309

public abstract Builder description(Optional<String> description);

310

public abstract Builder category(Optional<String> category);

311

312

public abstract Product build();

313

}

314

}

315

```

316

317

Usage:

318

319

```java

320

Product basic = Product.builder()

321

.name("Widget")

322

.price(19.99)

323

.build(); // Optional fields will be empty

324

325

Product detailed = Product.builder()

326

.name("Advanced Widget")

327

.price(39.99)

328

.description("A very advanced widget")

329

.category("Electronics")

330

.build();

331

```

332

333

## Generic Builders

334

335

Builders work with generic types:

336

337

```java { .api }

338

@AutoValue

339

public abstract class Container<T> {

340

public abstract T value();

341

public abstract String label();

342

343

public static <T> Builder<T> builder() {

344

return new AutoValue_Container.Builder<>();

345

}

346

347

@AutoValue.Builder

348

public abstract static class Builder<T> {

349

public abstract Builder<T> value(T value);

350

public abstract Builder<T> label(String label);

351

public abstract Container<T> build();

352

}

353

}

354

```

355

356

Usage:

357

358

```java

359

Container<String> stringContainer = Container.<String>builder()

360

.value("Hello")

361

.label("Greeting")

362

.build();

363

364

Container<Integer> intContainer = Container.<Integer>builder()

365

.value(42)

366

.label("Answer")

367

.build();

368

```

369

370

## Builder Inheritance

371

372

Builders can be used with inheritance hierarchies:

373

374

```java { .api }

375

public abstract class Animal {

376

public abstract String name();

377

public abstract int age();

378

}

379

380

@AutoValue

381

public abstract class Dog extends Animal {

382

public abstract String breed();

383

public abstract boolean trained();

384

385

public static Builder builder() {

386

return new AutoValue_Dog.Builder();

387

}

388

389

@AutoValue.Builder

390

public abstract static class Builder {

391

public abstract Builder name(String name);

392

public abstract Builder age(int age);

393

public abstract Builder breed(String breed);

394

public abstract Builder trained(boolean trained);

395

public abstract Dog build();

396

}

397

}

398

```