JavaPoet is a Java API for generating .java source files programmatically with support for modern Java features including records and sealed types
JavaPoet is a Java API for generating .java source files programmatically. It provides a fluent, type-safe interface for creating classes, interfaces, methods, fields, annotations, and complete Java source files. This Palantir-maintained fork includes support for modern Java features including record classes and sealed types with permitted subclasses.
implementation("com.palantir.javapoet:javapoet:0.11.0")<dependency>
<groupId>com.palantir.javapoet</groupId>
<artifactId>javapoet</artifactId>
<version>0.11.0</version>
</dependency>import com.palantir.javapoet.ClassName;
import com.palantir.javapoet.CodeBlock;
import com.palantir.javapoet.FieldSpec;
import com.palantir.javapoet.JavaFile;
import com.palantir.javapoet.MethodSpec;
import com.palantir.javapoet.TypeSpec;For type representations:
import com.palantir.javapoet.TypeName;
import com.palantir.javapoet.ParameterizedTypeName;
import com.palantir.javapoet.ArrayTypeName;
import com.palantir.javapoet.TypeVariableName;
import com.palantir.javapoet.WildcardTypeName;For annotations and parameters:
import com.palantir.javapoet.AnnotationSpec;
import com.palantir.javapoet.ParameterSpec;import com.palantir.javapoet.*;
import javax.lang.model.element.Modifier;
// Create a method
MethodSpec main = MethodSpec.methodBuilder("main")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(void.class)
.addParameter(String[].class, "args")
.addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
.build();
// Create a class with the method
TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(main)
.build();
// Create a Java file
JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build();
// Write to output
javaFile.writeTo(System.out);JavaPoet follows several key design principles:
toBuilder()TypeName class hierarchy for representing all Java typesjava.lang.reflect) and annotation processing (javax.lang.model) APIsJavaPoet uses special placeholders in format strings for code generation:
$L - Literals (strings, primitives, emitted as-is)$S - String literals (automatically escaped and quoted)$T - Types (automatically imported and referenced correctly)$N - Names (identifiers for methods, fields, parameters)$$ - Escaped dollar signCreate complete Java source files with package declarations, imports, and type definitions. JavaFile handles import management automatically.
class JavaFile {
static Builder builder(String packageName, TypeSpec typeSpec);
void writeTo(Appendable out) throws IOException;
void writeTo(File directory) throws IOException;
void writeTo(Path directory) throws IOException;
String toString();
}Build type declarations including classes, interfaces, enums, records, and annotation types. TypeSpec provides a unified builder API for all type kinds.
class TypeSpec {
static Builder classBuilder(String name);
static Builder classBuilder(ClassName className);
static Builder interfaceBuilder(String name);
static Builder enumBuilder(String name);
static Builder recordBuilder(String name);
static Builder annotationBuilder(String name);
static Builder anonymousClassBuilder(String typeArgumentsFormat, Object... args);
enum Kind {
CLASS, RECORD, INTERFACE, ENUM, ANNOTATION
}
}Define methods and constructors with parameters, return types, exceptions, modifiers, and code bodies. Includes support for varargs, type variables, and annotation method defaults.
class MethodSpec {
static Builder methodBuilder(String name);
static Builder constructorBuilder();
static Builder compactConstructorBuilder();
static Builder overriding(ExecutableElement method);
}Create field declarations with types, names, modifiers, javadoc, annotations, and initializers.
class FieldSpec {
static Builder builder(TypeName type, String name, Modifier... modifiers);
static Builder builder(Type type, String name, Modifier... modifiers);
}Define method and constructor parameters with types, names, modifiers, and annotations.
class ParameterSpec {
static ParameterSpec get(VariableElement element);
static Builder builder(TypeName type, String name, Modifier... modifiers);
static Builder builder(Type type, String name, Modifier... modifiers);
}Represent code fragments with format strings, placeholders, control flow, and statements. CodeBlock handles indentation and formatting automatically.
class CodeBlock {
static CodeBlock of(String format, Object... args);
static CodeBlock join(Iterable<CodeBlock> codeBlocks, String separator);
static Collector<CodeBlock, ?, CodeBlock> joining(String separator);
static Builder builder();
}Create annotation instances with members and values for use on types, methods, fields, and parameters.
class AnnotationSpec {
static final String VALUE = "value";
static AnnotationSpec get(Annotation annotation);
static AnnotationSpec get(AnnotationMirror annotation);
static Builder builder(ClassName type);
static Builder builder(Class<?> type);
}Represent Java types including primitives, classes, arrays, generics, type variables, and wildcards. TypeName provides the foundation for type-safe code generation.
class TypeName {
static final TypeName VOID;
static final TypeName BOOLEAN;
static final TypeName BYTE;
static final TypeName SHORT;
static final TypeName INT;
static final TypeName LONG;
static final TypeName CHAR;
static final TypeName FLOAT;
static final TypeName DOUBLE;
static TypeName get(TypeMirror mirror);
static TypeName get(Type type);
TypeName box();
TypeName unbox();
boolean isPrimitive();
boolean isBoxedPrimitive();
}Represent class and interface names with package information, support for nested classes, and comparison capabilities.
class ClassName extends TypeName implements Comparable<ClassName> {
static final ClassName OBJECT;
static ClassName get(Class<?> clazz);
static ClassName get(String packageName, String simpleName, String... simpleNames);
static ClassName get(TypeElement element);
static ClassName bestGuess(String classNameString);
ClassName peerClass(String name);
ClassName nestedClass(String name);
}Represent generic types with type arguments (e.g., List<String>, Map<K, V>).
class ParameterizedTypeName extends TypeName {
static ParameterizedTypeName get(ClassName rawType, TypeName... typeArguments);
static ParameterizedTypeName get(Class<?> rawType, Type... typeArguments);
static ParameterizedTypeName get(ParameterizedType type);
ParameterizedTypeName nestedClass(String name);
ParameterizedTypeName nestedClass(String name, List<TypeName> typeArguments);
}Represent type variables (e.g., T, E, K, V) with optional bounds.
class TypeVariableName extends TypeName {
static TypeVariableName get(String name);
static TypeVariableName get(String name, TypeName... bounds);
static TypeVariableName get(TypeVariable mirror);
static TypeVariableName get(TypeParameterElement element);
TypeVariableName withBounds(TypeName... bounds);
}Represent array types with component type information.
class ArrayTypeName extends TypeName {
static ArrayTypeName of(TypeName componentType);
static ArrayTypeName of(Type componentType);
static ArrayTypeName get(ArrayType mirror);
}Represent wildcard types with upper and lower bounds (e.g., ? extends Number, ? super Integer).
class WildcardTypeName extends TypeName {
static WildcardTypeName subtypeOf(TypeName upperBound);
static WildcardTypeName subtypeOf(Type upperBound);
static WildcardTypeName supertypeOf(TypeName lowerBound);
static WildcardTypeName supertypeOf(Type lowerBound);
}Manage unique Java identifiers and avoid name collisions in generated code.
class NameAllocator implements Cloneable {
NameAllocator();
String newName(String suggestion);
String newName(String suggestion, Object tag);
String get(Object tag);
NameAllocator clone();
static String toJavaIdentifier(String suggestion);
}Install with Tessl CLI
npx tessl i tessl/maven-com-palantir-javapoet--javapoet@0.11.0