or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-types.mdcode-generation.mdcode-specifications.mdfile-management.mdindex.mdtype-system.md

advanced-types.mddocs/

0

# Advanced Type System

1

2

Advanced type representations for complex generic scenarios including parameterized types, arrays, type variables, and wildcards. These types enable full support for Java's generic type system.

3

4

## Capabilities

5

6

### ParameterizedTypeName

7

8

Represents parameterized types like `List<String>`, `Map<String, Integer>`, or `Optional<? extends Number>`. Handles generic type arguments and nested parameterization.

9

10

```java { .api }

11

/**

12

* Represents parameterized types like List<String>, Map<K,V>

13

*/

14

public final class ParameterizedTypeName extends TypeName {

15

// Public fields

16

public final ClassName rawType;

17

public final List<TypeName> typeArguments;

18

19

// Static factory methods

20

public static ParameterizedTypeName get(ClassName rawType, TypeName... typeArguments);

21

public static ParameterizedTypeName get(Class<?> rawType, Type... typeArguments);

22

public static ParameterizedTypeName get(ParameterizedType type);

23

24

// Instance methods

25

public ParameterizedTypeName annotated(List<AnnotationSpec> annotations);

26

public TypeName withoutAnnotations();

27

public ParameterizedTypeName nestedClass(String name);

28

public ParameterizedTypeName nestedClass(String name, List<TypeName> typeArguments);

29

}

30

```

31

32

**Usage Examples:**

33

34

```java

35

// Simple parameterized types

36

ParameterizedTypeName listString = ParameterizedTypeName.get(List.class, String.class);

37

ParameterizedTypeName setInteger = ParameterizedTypeName.get(Set.class, Integer.class);

38

39

// Map with key-value types

40

ParameterizedTypeName mapStringInt = ParameterizedTypeName.get(

41

ClassName.get(Map.class),

42

ClassName.get(String.class),

43

ClassName.get(Integer.class)

44

);

45

46

// Nested parameterization

47

ParameterizedTypeName listOfMaps = ParameterizedTypeName.get(

48

List.class,

49

ParameterizedTypeName.get(Map.class, String.class, Object.class)

50

); // List<Map<String, Object>>

51

52

// Complex generic types

53

ParameterizedTypeName functionType = ParameterizedTypeName.get(

54

Function.class,

55

String.class,

56

ParameterizedTypeName.get(Optional.class, Integer.class)

57

); // Function<String, Optional<Integer>>

58

59

// Using with wildcards

60

ParameterizedTypeName wildcardList = ParameterizedTypeName.get(

61

List.class,

62

WildcardTypeName.subtypeOf(Number.class)

63

); // List<? extends Number>

64

65

// From reflection

66

ParameterizedType reflectionType = ...; // obtained from reflection

67

ParameterizedTypeName fromReflection = ParameterizedTypeName.get(reflectionType);

68

```

69

70

### ArrayTypeName

71

72

Represents array types like `String[]`, `int[][]`, or `List<String>[]`. Supports multi-dimensional arrays and arrays of complex types.

73

74

```java { .api }

75

/**

76

* Represents array types like String[], int[][], List<String>[]

77

*/

78

public final class ArrayTypeName extends TypeName {

79

// Public fields

80

public final TypeName componentType;

81

82

// Static factory methods

83

public static ArrayTypeName of(TypeName componentType);

84

public static ArrayTypeName of(Type componentType);

85

public static ArrayTypeName get(ArrayType mirror);

86

public static ArrayTypeName get(GenericArrayType type);

87

88

// Instance methods

89

public ArrayTypeName annotated(List<AnnotationSpec> annotations);

90

public TypeName withoutAnnotations();

91

}

92

```

93

94

**Usage Examples:**

95

96

```java

97

// Primitive arrays

98

ArrayTypeName intArray = ArrayTypeName.of(TypeName.INT); // int[]

99

ArrayTypeName byteArray = ArrayTypeName.of(TypeName.BYTE); // byte[]

100

101

// Object arrays

102

ArrayTypeName stringArray = ArrayTypeName.of(String.class); // String[]

103

ArrayTypeName objectArray = ArrayTypeName.of(Object.class); // Object[]

104

105

// Multi-dimensional arrays

106

ArrayTypeName intMatrix = ArrayTypeName.of(

107

ArrayTypeName.of(TypeName.INT)

108

); // int[][]

109

110

ArrayTypeName stringMatrix = ArrayTypeName.of(

111

ArrayTypeName.of(String.class)

112

); // String[][]

113

114

// Arrays of parameterized types

115

ArrayTypeName listArray = ArrayTypeName.of(

116

ParameterizedTypeName.get(List.class, String.class)

117

); // List<String>[]

118

119

// Arrays of custom types

120

ClassName customType = ClassName.get("com.example", "CustomClass");

121

ArrayTypeName customArray = ArrayTypeName.of(customType); // CustomClass[]

122

123

// Using in method signatures

124

MethodSpec method = MethodSpec.methodBuilder("processArrays")

125

.addParameter(ArrayTypeName.of(String.class), "names")

126

.addParameter(ArrayTypeName.of(ArrayTypeName.of(TypeName.INT)), "matrix")

127

.returns(ArrayTypeName.of(Object.class))

128

.addStatement("// Process arrays")

129

.build();

130

131

// From reflection

132

Method reflectionMethod = SomeClass.class.getMethod("arrayMethod", String[].class);

133

Type arrayType = reflectionMethod.getGenericParameterTypes()[0];

134

ArrayTypeName fromReflection = (ArrayTypeName) TypeName.get(arrayType);

135

```

136

137

### TypeVariableName

138

139

Represents type variables like `T`, `E`, `K`, `V` used in generic class and method declarations. Supports bounded type variables.

140

141

```java { .api }

142

/**

143

* Represents type variables like T, E, K, V in generic declarations

144

*/

145

public final class TypeVariableName extends TypeName {

146

// Public fields

147

public final String name;

148

public final List<TypeName> bounds;

149

150

// Static factory methods

151

public static TypeVariableName get(String name);

152

public static TypeVariableName get(String name, TypeName... bounds);

153

public static TypeVariableName get(String name, Type... bounds);

154

public static TypeVariableName get(TypeVariable mirror);

155

public static TypeVariableName get(TypeParameterElement element);

156

public static TypeVariableName get(java.lang.reflect.TypeVariable<?> type);

157

158

// Instance methods

159

public TypeVariableName annotated(List<AnnotationSpec> annotations);

160

public TypeName withoutAnnotations();

161

public TypeVariableName withBounds(Type... bounds);

162

public TypeVariableName withBounds(TypeName... bounds);

163

public TypeVariableName withBounds(List<? extends TypeName> bounds);

164

}

165

```

166

167

**Usage Examples:**

168

169

```java

170

// Simple unbounded type variables

171

TypeVariableName T = TypeVariableName.get("T");

172

TypeVariableName E = TypeVariableName.get("E");

173

TypeVariableName K = TypeVariableName.get("K");

174

TypeVariableName V = TypeVariableName.get("V");

175

176

// Bounded type variables

177

TypeVariableName numberT = TypeVariableName.get("T", Number.class);

178

TypeVariableName comparableT = TypeVariableName.get("T", Comparable.class);

179

180

// Multiple bounds

181

TypeVariableName multibound = TypeVariableName.get("T",

182

ClassName.get(Serializable.class),

183

ClassName.get(Comparable.class)

184

); // T extends Serializable & Comparable

185

186

// Complex bounds with parameterized types

187

TypeVariableName complexBound = TypeVariableName.get("T",

188

ParameterizedTypeName.get(Comparable.class, TypeVariableName.get("T"))

189

); // T extends Comparable<T>

190

191

// Using in generic class

192

TypeSpec genericClass = TypeSpec.classBuilder("Container")

193

.addTypeVariable(TypeVariableName.get("T"))

194

.addField(TypeVariableName.get("T"), "value", Modifier.PRIVATE)

195

.addMethod(MethodSpec.methodBuilder("getValue")

196

.addModifiers(Modifier.PUBLIC)

197

.returns(TypeVariableName.get("T"))

198

.addStatement("return value")

199

.build())

200

.addMethod(MethodSpec.methodBuilder("setValue")

201

.addModifiers(Modifier.PUBLIC)

202

.addParameter(TypeVariableName.get("T"), "value")

203

.addStatement("this.value = value")

204

.build())

205

.build();

206

207

// Using in generic method

208

MethodSpec genericMethod = MethodSpec.methodBuilder("swap")

209

.addModifiers(Modifier.PUBLIC, Modifier.STATIC)

210

.addTypeVariable(TypeVariableName.get("T"))

211

.addParameter(ArrayTypeName.of(TypeVariableName.get("T")), "array")

212

.addParameter(TypeName.INT, "i")

213

.addParameter(TypeName.INT, "j")

214

.addStatement("T temp = array[i]")

215

.addStatement("array[i] = array[j]")

216

.addStatement("array[j] = temp")

217

.build();

218

219

// Bounded generic method

220

MethodSpec boundedMethod = MethodSpec.methodBuilder("max")

221

.addModifiers(Modifier.PUBLIC, Modifier.STATIC)

222

.addTypeVariable(TypeVariableName.get("T",

223

ParameterizedTypeName.get(Comparable.class, TypeVariableName.get("T"))))

224

.addParameter(TypeVariableName.get("T"), "a")

225

.addParameter(TypeVariableName.get("T"), "b")

226

.returns(TypeVariableName.get("T"))

227

.addStatement("return a.compareTo(b) > 0 ? a : b")

228

.build();

229

```

230

231

### WildcardTypeName

232

233

Represents wildcard types like `? extends String`, `? super Integer`, or unbounded `?`. Essential for flexible generic APIs.

234

235

```java { .api }

236

/**

237

* Represents wildcard types like ? extends String, ? super Integer

238

*/

239

public final class WildcardTypeName extends TypeName {

240

// Public fields

241

public final List<TypeName> upperBounds;

242

public final List<TypeName> lowerBounds;

243

244

// Static factory methods

245

public static WildcardTypeName subtypeOf(TypeName upperBound);

246

public static WildcardTypeName subtypeOf(Type upperBound);

247

public static WildcardTypeName supertypeOf(TypeName lowerBound);

248

public static WildcardTypeName supertypeOf(Type lowerBound);

249

public static TypeName get(javax.lang.model.type.WildcardType mirror);

250

public static TypeName get(WildcardType wildcardName);

251

252

// Instance methods

253

public WildcardTypeName annotated(List<AnnotationSpec> annotations);

254

public TypeName withoutAnnotations();

255

}

256

```

257

258

**Usage Examples:**

259

260

```java

261

// Upper bounded wildcards (? extends Type)

262

WildcardTypeName extendsNumber = WildcardTypeName.subtypeOf(Number.class);

263

WildcardTypeName extendsString = WildcardTypeName.subtypeOf(String.class);

264

265

// Lower bounded wildcards (? super Type)

266

WildcardTypeName superInteger = WildcardTypeName.supertypeOf(Integer.class);

267

WildcardTypeName superString = WildcardTypeName.supertypeOf(String.class);

268

269

// Using with parameterized types

270

ParameterizedTypeName listExtendsNumber = ParameterizedTypeName.get(

271

List.class,

272

WildcardTypeName.subtypeOf(Number.class)

273

); // List<? extends Number>

274

275

ParameterizedTypeName listSuperInteger = ParameterizedTypeName.get(

276

List.class,

277

WildcardTypeName.supertypeOf(Integer.class)

278

); // List<? super Integer>

279

280

// Consumer/Producer patterns (PECS - Producer Extends, Consumer Super)

281

MethodSpec copyMethod = MethodSpec.methodBuilder("copy")

282

.addModifiers(Modifier.PUBLIC, Modifier.STATIC)

283

.addTypeVariable(TypeVariableName.get("T"))

284

.addParameter(ParameterizedTypeName.get(List.class,

285

WildcardTypeName.subtypeOf(TypeVariableName.get("T"))), "src") // Producer

286

.addParameter(ParameterizedTypeName.get(List.class,

287

WildcardTypeName.supertypeOf(TypeVariableName.get("T"))), "dest") // Consumer

288

.addStatement("for (T item : src) dest.add(item)")

289

.build();

290

291

// Complex wildcard scenarios

292

ParameterizedTypeName complexWildcard = ParameterizedTypeName.get(

293

Map.class,

294

WildcardTypeName.subtypeOf(String.class),

295

WildcardTypeName.supertypeOf(

296

ParameterizedTypeName.get(List.class, Integer.class)

297

)

298

); // Map<? extends String, ? super List<Integer>>

299

300

// Unbounded wildcard (? - rarely used directly)

301

// Usually represented as WildcardTypeName.subtypeOf(Object.class)

302

WildcardTypeName unbounded = WildcardTypeName.subtypeOf(Object.class);

303

304

// Method accepting flexible collections

305

MethodSpec printAll = MethodSpec.methodBuilder("printAll")

306

.addModifiers(Modifier.PUBLIC, Modifier.STATIC)

307

.addParameter(ParameterizedTypeName.get(Collection.class,

308

WildcardTypeName.subtypeOf(Object.class)), "items")

309

.addStatement("for (Object item : items) $T.out.println(item)", System.class)

310

.build();

311

```

312

313

### Type Composition and Complex Scenarios

314

315

Combining multiple advanced types for complex generic scenarios:

316

317

```java

318

// Repository pattern with complex generics

319

TypeVariableName entityT = TypeVariableName.get("T");

320

TypeVariableName idT = TypeVariableName.get("ID", Serializable.class);

321

322

TypeSpec repository = TypeSpec.interfaceBuilder("Repository")

323

.addModifiers(Modifier.PUBLIC)

324

.addTypeVariable(entityT)

325

.addTypeVariable(idT)

326

.addMethod(MethodSpec.methodBuilder("findById")

327

.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)

328

.addParameter(idT, "id")

329

.returns(ParameterizedTypeName.get(Optional.class, entityT))

330

.build())

331

.addMethod(MethodSpec.methodBuilder("findAll")

332

.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)

333

.returns(ParameterizedTypeName.get(List.class, entityT))

334

.build())

335

.addMethod(MethodSpec.methodBuilder("save")

336

.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)

337

.addParameter(entityT, "entity")

338

.returns(entityT)

339

.build())

340

.build();

341

342

// Event handler with complex type relationships

343

TypeVariableName eventT = TypeVariableName.get("E",

344

ClassName.get("com.example", "Event"));

345

346

MethodSpec handleEvents = MethodSpec.methodBuilder("handleEvents")

347

.addModifiers(Modifier.PUBLIC)

348

.addTypeVariable(eventT)

349

.addParameter(ParameterizedTypeName.get(List.class,

350

WildcardTypeName.subtypeOf(eventT)), "events")

351

.addParameter(ParameterizedTypeName.get(Consumer.class,

352

WildcardTypeName.supertypeOf(eventT)), "handler")

353

.addStatement("events.forEach(handler)")

354

.build();

355

356

// Generic builder pattern

357

TypeVariableName builderT = TypeVariableName.get("T");

358

TypeVariableName builderB = TypeVariableName.get("B",

359

ParameterizedTypeName.get(ClassName.get("Builder"), builderT));

360

361

TypeSpec builder = TypeSpec.classBuilder("Builder")

362

.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)

363

.addTypeVariable(builderT)

364

.addTypeVariable(builderB)

365

.addMethod(MethodSpec.methodBuilder("build")

366

.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)

367

.returns(builderT)

368

.build())

369

.build();

370

```

371

372

### Working with Annotations on Advanced Types

373

374

Advanced types support type annotations:

375

376

```java

377

// Annotated type parameters

378

TypeVariableName annotatedT = TypeVariableName.get("T")

379

.annotated(AnnotationSpec.builder(NonNull.class).build());

380

381

// Annotated parameterized types

382

ParameterizedTypeName annotatedList = ParameterizedTypeName.get(List.class, String.class)

383

.annotated(AnnotationSpec.builder(Immutable.class).build());

384

385

// Annotated wildcards

386

WildcardTypeName annotatedWildcard = WildcardTypeName.subtypeOf(String.class)

387

.annotated(AnnotationSpec.builder(NonNull.class).build());

388

389

// Using annotated types in method signatures

390

MethodSpec annotatedMethod = MethodSpec.methodBuilder("processData")

391

.addParameter(annotatedList, "data")

392

.addParameter(ParameterizedTypeName.get(Optional.class, annotatedT), "context")

393

.returns(ArrayTypeName.of(annotatedT).annotated(

394

AnnotationSpec.builder(NonNull.class).build()))

395

.build();

396

```