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

value-classes.mddocs/

0

# Value Classes

1

2

AutoValue generates immutable value classes that automatically implement equals(), hashCode(), and toString() methods with proper value semantics. Value classes are defined as abstract classes with abstract property getter methods.

3

4

## Basic Value Class

5

6

```java { .api }

7

@AutoValue

8

public abstract class BasicExample {

9

public abstract String name();

10

public abstract int age();

11

12

public static BasicExample create(String name, int age) {

13

return new AutoValue_BasicExample(name, age);

14

}

15

}

16

```

17

18

The generated class `AutoValue_BasicExample` will:

19

- Implement all abstract methods

20

- Provide proper equals() and hashCode() based on all properties

21

- Generate a readable toString() representation

22

- Be immutable (all fields are final)

23

24

## Usage Example

25

26

```java

27

BasicExample person = BasicExample.create("Alice", 30);

28

BasicExample samePerson = BasicExample.create("Alice", 30);

29

BasicExample differentPerson = BasicExample.create("Bob", 25);

30

31

System.out.println(person); // BasicExample{name=Alice, age=30}

32

System.out.println(person.equals(samePerson)); // true

33

System.out.println(person.equals(differentPerson)); // false

34

System.out.println(person.hashCode() == samePerson.hashCode()); // true

35

```

36

37

## Property Types

38

39

AutoValue supports all Java types as properties:

40

41

```java { .api }

42

@AutoValue

43

public abstract class TypesExample {

44

// Primitives

45

public abstract int intValue();

46

public abstract long longValue();

47

public abstract boolean booleanValue();

48

public abstract double doubleValue();

49

50

// Object types

51

public abstract String stringValue();

52

public abstract List<String> listValue();

53

public abstract Optional<Integer> optionalValue();

54

55

// Custom types

56

public abstract CustomClass customValue();

57

58

// Arrays

59

public abstract String[] arrayValue();

60

61

public static TypesExample create(

62

int intValue,

63

long longValue,

64

boolean booleanValue,

65

double doubleValue,

66

String stringValue,

67

List<String> listValue,

68

Optional<Integer> optionalValue,

69

CustomClass customValue,

70

String[] arrayValue) {

71

return new AutoValue_TypesExample(

72

intValue, longValue, booleanValue, doubleValue,

73

stringValue, listValue, optionalValue, customValue, arrayValue);

74

}

75

}

76

```

77

78

## Nullable Properties

79

80

Properties can be marked as nullable using any annotation named "Nullable":

81

82

```java { .api }

83

@AutoValue

84

public abstract class NullableExample {

85

@Nullable

86

public abstract String nullableProperty();

87

88

public abstract String requiredProperty();

89

90

public static NullableExample create(@Nullable String nullableProperty, String requiredProperty) {

91

return new AutoValue_NullableExample(nullableProperty, requiredProperty);

92

}

93

}

94

```

95

96

## Generic Value Classes

97

98

AutoValue supports generic type parameters:

99

100

```java { .api }

101

@AutoValue

102

public abstract class GenericExample<T, U> {

103

public abstract T firstValue();

104

public abstract U secondValue();

105

106

public static <T, U> GenericExample<T, U> create(T firstValue, U secondValue) {

107

return new AutoValue_GenericExample<>(firstValue, secondValue);

108

}

109

}

110

```

111

112

## Inheritance and Interfaces

113

114

AutoValue classes can implement interfaces and extend abstract classes:

115

116

```java { .api }

117

public interface Identifiable {

118

String getId();

119

}

120

121

@AutoValue

122

public abstract class IdentifiableEntity implements Identifiable {

123

@Override

124

public abstract String getId();

125

public abstract String name();

126

127

public static IdentifiableEntity create(String id, String name) {

128

return new AutoValue_IdentifiableEntity(id, name);

129

}

130

}

131

```

132

133

## Custom Methods

134

135

You can add custom methods to AutoValue classes:

136

137

```java { .api }

138

@AutoValue

139

public abstract class PersonWithMethods {

140

public abstract String firstName();

141

public abstract String lastName();

142

public abstract int age();

143

144

// Custom method

145

public String fullName() {

146

return firstName() + " " + lastName();

147

}

148

149

// Custom predicate

150

public boolean isAdult() {

151

return age() >= 18;

152

}

153

154

public static PersonWithMethods create(String firstName, String lastName, int age) {

155

return new AutoValue_PersonWithMethods(firstName, lastName, age);

156

}

157

}

158

```

159

160

## Annotation Copying

161

162

Control which annotations are copied to the generated implementation:

163

164

```java { .api }

165

@AutoValue

166

@CopyAnnotations // Copy class-level annotations

167

public abstract class AnnotatedExample {

168

@CopyAnnotations

169

@SuppressWarnings("example")

170

public abstract String annotatedProperty();

171

172

@CopyAnnotations(exclude = {Deprecated.class})

173

@Deprecated

174

@SuppressWarnings("example")

175

public abstract String selectivelyAnnotatedProperty();

176

177

public static AnnotatedExample create(String annotatedProperty, String selectivelyAnnotatedProperty) {

178

return new AutoValue_AnnotatedExample(annotatedProperty, selectivelyAnnotatedProperty);

179

}

180

}

181

```

182

183

## Validation

184

185

Add validation to factory methods:

186

187

```java { .api }

188

@AutoValue

189

public abstract class ValidatedExample {

190

public abstract String email();

191

public abstract int age();

192

193

public static ValidatedExample create(String email, int age) {

194

checkArgument(email.contains("@"), "Invalid email: %s", email);

195

checkArgument(age >= 0, "Age must be non-negative: %s", age);

196

return new AutoValue_ValidatedExample(email, age);

197

}

198

199

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

200

if (!condition) {

201

throw new IllegalArgumentException(String.format(message, args));

202

}

203

}

204

}

205

```

206

207

## Collection Properties

208

209

AutoValue works well with immutable collections:

210

211

```java { .api }

212

@AutoValue

213

public abstract class CollectionExample {

214

public abstract ImmutableList<String> items();

215

public abstract ImmutableSet<Integer> values();

216

public abstract ImmutableMap<String, Object> properties();

217

218

public static CollectionExample create(

219

Iterable<String> items,

220

Iterable<Integer> values,

221

Map<String, Object> properties) {

222

return new AutoValue_CollectionExample(

223

ImmutableList.copyOf(items),

224

ImmutableSet.copyOf(values),

225

ImmutableMap.copyOf(properties));

226

}

227

}

228

```

229

230

## Error Handling

231

232

AutoValue generated constructors validate non-null parameters:

233

234

```java

235

// This will throw NullPointerException

236

PersonExample person = PersonExample.create(null, 25); // NPE: name cannot be null

237

238

// Use Optional for nullable values instead

239

@AutoValue

240

public abstract class SafeExample {

241

public abstract Optional<String> optionalName();

242

public abstract int age();

243

244

public static SafeExample create(@Nullable String name, int age) {

245

return new AutoValue_SafeExample(Optional.ofNullable(name), age);

246

}

247

}

248

```

249

250

## Performance Considerations

251

252

- Generated equals() methods use efficient short-circuiting

253

- hashCode() is computed once and cached

254

- toString() builds strings efficiently

255

- All fields are final, enabling JVM optimizations

256

- No reflection is used at runtime