codegentle-java 模块为生成 Java 源代码提供全面的规范。本文档涵盖了所有 Java 特定的 Spec 类、它们的构造方法、属性和独特的 Java 语言功能。
所有 Java 规范的基础接口。
public interface JavaSpec : Spec {
fun emit(codeWriter: JavaCodeWriter)
}功能:
- 扩展通用
Spec接口 - 提供向
JavaCodeWriter发射的功能 - 所有 Java 特定规范类型的基础
所有 Java 类型声明(类、接口、枚举等)的密封接口。
public sealed interface JavaTypeSpec : JavaSpec {
val name: String?
val kind: Kind
val javadoc: CodeValue
val annotations: List<AnnotationRef>
val modifiers: Set<JavaModifier>
val typeVariables: List<TypeRef<TypeVariableName>>
val superclass: TypeName?
val superinterfaces: List<TypeName>
val fields: List<JavaFieldSpec>
val staticBlock: CodeValue
val initializerBlock: CodeValue
val methods: List<JavaMethodSpec>
val subtypes: List<JavaTypeSpec>
}属性:
name- 类型名称(匿名类型可为 null)kind- 类型种类(CLASS、INTERFACE、ENUM 等)javadoc- 文档注释annotations- 类型注解modifiers- 访问修饰符和关键字typeVariables- 泛型类型参数superclass- 扩展的类(如果适用)superinterfaces- 实现的接口fields- 字段声明staticBlock- 静态初始化块initializerBlock- 实例初始化块methods- 方法声明subtypes- 嵌套类型
具有特定行为的 Java 类型种类枚举:
enum class Kind {
CLASS, // 标准类
INTERFACE, // 接口
ENUM, // 枚举类型
ANNOTATION, // 注解类型
RECORD, // 记录类型(Java 14+)
SEALED_CLASS, // 密封类(Java 17+)
NON_SEALED_CLASS, // 非密封类
SEALED_INTERFACE, // 密封接口
NON_SEALED_INTERFACE // 非密封接口
}种类特定功能:
- INTERFACE:字段隐式
public static final,方法隐式public abstract - ENUM:支持枚举常量,仅实现接口
- ANNOTATION:支持方法默认值
- RECORD:带自动访问器的不可变数据载体
- SEALED_*:受限制的继承层次结构
简单类型(类和接口)的规范。
public interface JavaSimpleTypeSpec : NamedSpec, JavaTypeSpec {
override val name: String
}构造:
// DSL 构造(推荐)
val classSpec = JavaSimpleTypeSpec(JavaTypeSpec.Kind.CLASS, "MyClass") {
addModifier(JavaModifier.PUBLIC)
addDoc("一个简单的示例类。")
addField(JavaFieldSpec("field", JavaClassNames.STRING.ref()) {
addModifier(JavaModifier.PRIVATE)
initializer("\"default\"")
})
addMethod(JavaMethodSpec("getField") {
addModifier(JavaModifier.PUBLIC)
returns(JavaClassNames.STRING.ref())
addCode("return this.field;")
})
}
// 构建器构造
val classSpec = JavaSimpleTypeSpec.builder(JavaTypeSpec.Kind.CLASS, "MyClass")
.addModifier(JavaModifier.PUBLIC)
.addDoc("一个简单的示例类。")
.build()生成的输出:
/**
* 一个简单的示例类。
*/
public class MyClass {
private String field = "default";
public String getField() {
return this.field;
}
}Java 枚举类型的规范。
public interface JavaEnumTypeSpec : NamedSpec, JavaTypeSpec {
val enumConstants: List<JavaFieldSpec>
}构造:
val enumSpec = JavaEnumTypeSpec("Color") {
addModifier(JavaModifier.PUBLIC)
addDoc("RGB 颜色枚举。")
addEnumConstant("RED")
addEnumConstant("GREEN")
addEnumConstant("BLUE")
addMethod(JavaMethodSpec("isWarm") {
addModifier(JavaModifier.PUBLIC)
returns(JavaPrimitiveTypeNames.BOOLEAN.ref())
addCode("return this == RED;")
})
}生成的输出:
/**
* RGB 颜色枚举。
*/
public enum Color {
RED,
GREEN,
BLUE;
public boolean isWarm() {
return this == RED;
}
}Java 记录类型的规范(Java 14+)。
public interface JavaRecordTypeSpec : NamedSpec, JavaTypeSpec {
val recordComponents: List<JavaParameterSpec>
}构造:
val recordSpec = JavaRecordTypeSpec("Person") {
addModifier(JavaModifier.PUBLIC)
addDoc("人员记录。")
addRecordComponent(JavaParameterSpec("name", JavaClassNames.STRING.ref()))
addRecordComponent(JavaParameterSpec("age", JavaPrimitiveTypeNames.INT.ref()))
addMethod(JavaMethodSpec("isAdult") {
addModifier(JavaModifier.PUBLIC)
returns(JavaPrimitiveTypeNames.BOOLEAN.ref())
addCode("return age >= 18;")
})
}生成的输出:
/**
* 人员记录。
*/
public record Person(String name, int age) {
public boolean isAdult() {
return age >= 18;
}
}Java 注解类型的规范。
public interface JavaAnnotationTypeSpec : NamedSpec, JavaTypeSpec {
// 注解特定属性
}构造:
val annotationSpec = JavaAnnotationTypeSpec("MyAnnotation") {
addModifier(JavaModifier.PUBLIC)
addDoc("自定义注解。")
addMethod(JavaMethodSpec("value") {
addModifier(JavaModifier.PUBLIC, JavaModifier.ABSTRACT)
returns(JavaClassNames.STRING.ref())
defaultValue("\"default\"")
})
addMethod(JavaMethodSpec("required") {
addModifier(JavaModifier.PUBLIC, JavaModifier.ABSTRACT)
returns(JavaPrimitiveTypeNames.BOOLEAN.ref())
defaultValue("false")
})
}生成的输出:
/**
* 自定义注解。
*/
public @interface MyAnnotation {
String value() default "default";
boolean required() default false;
}Java 方法和构造函数的规范。
public interface JavaMethodSpec : JavaSpec, NamedSpec, JavaModifierContainer {
val name: String
val javadoc: CodeValue
val annotations: List<AnnotationRef>
val modifiers: Set<JavaModifier>
val typeVariables: List<TypeRef<TypeVariableName>>
val returnType: TypeRef<*>?
val parameters: List<JavaParameterSpec>
val isVarargs: Boolean
val exceptions: List<TypeRef<*>>
val code: CodeValue
val defaultValue: CodeValue
val isConstructor: Boolean
}构造:
// 常规方法
val methodSpec = JavaMethodSpec("calculateSum") {
addModifier(JavaModifier.PUBLIC, JavaModifier.STATIC)
addDoc("计算两个整数的和。")
returns(JavaPrimitiveTypeNames.INT.ref())
addParameter(JavaParameterSpec("a", JavaPrimitiveTypeNames.INT.ref()))
addParameter(JavaParameterSpec("b", JavaPrimitiveTypeNames.INT.ref()))
addCode("return a + b;")
}
// 构造函数
val constructorSpec = JavaMethodSpec {
addModifier(JavaModifier.PUBLIC)
addParameter(JavaParameterSpec("name", JavaClassNames.STRING.ref()))
addCode("this.name = name;")
}
// 可变参数方法
val varargsMethodSpec = JavaMethodSpec("sum") {
addModifier(JavaModifier.PUBLIC, JavaModifier.STATIC)
returns(JavaPrimitiveTypeNames.INT.ref())
addParameter(JavaParameterSpec("numbers", JavaPrimitiveTypeNames.INT.arrayType().ref()))
varargs()
addCode("""
int sum = 0;
for (int number : numbers) {
sum += number;
}
return sum;
""".trimIndent())
}
// 带异常的方法
val methodWithExceptions = JavaMethodSpec("readFile") {
addModifier(JavaModifier.PUBLIC)
returns(JavaClassNames.STRING.ref())
addParameter(JavaParameterSpec("path", JavaClassNames.STRING.ref()))
addException(ClassName("java.io", "IOException").ref())
addCode("// 文件读取代码")
}生成的输出:
/**
* 计算两个整数的和。
*/
public static int calculateSum(int a, int b) {
return a + b;
}
public MyClass(String name) {
this.name = name;
}
public static int sum(int... numbers) {
int sum = 0;
for (int number : numbers) {
sum += number;
}
return sum;
}
public String readFile(String path) throws IOException {
// 文件读取代码
}Java 字段的规范。
public interface JavaFieldSpec : JavaSpec, NamedSpec, JavaModifierContainer {
val name: String
val type: TypeRef<*>
val javadoc: CodeValue
val annotations: List<AnnotationRef>
val modifiers: Set<JavaModifier>
val initializer: CodeValue
}构造:
// 简单字段
val fieldSpec = JavaFieldSpec("name", JavaClassNames.STRING.ref()) {
addModifier(JavaModifier.PRIVATE)
addDoc("名称字段。")
}
// 带初始化器的字段
val initializedFieldSpec = JavaFieldSpec("count", JavaPrimitiveTypeNames.INT.ref()) {
addModifier(JavaModifier.PRIVATE, JavaModifier.STATIC)
initializer("0")
}
// 常量字段
val constantSpec = JavaFieldSpec("MAX_SIZE", JavaPrimitiveTypeNames.INT.ref()) {
addModifier(JavaModifier.PUBLIC, JavaModifier.STATIC, JavaModifier.FINAL)
initializer("1000")
}
// 泛型字段
val listFieldSpec = JavaFieldSpec("items",
ParameterizedTypeName.get(
ClassName("java.util", "List"),
JavaClassNames.STRING
).ref()
) {
addModifier(JavaModifier.PRIVATE)
initializer("new %V()", CodePart.type(ClassName("java.util", "ArrayList")))
}生成的输出:
/**
* 名称字段。
*/
private String name;
private static int count = 0;
public static final int MAX_SIZE = 1000;
private List<String> items = new ArrayList<>();方法/构造函数参数的规范。
public interface JavaParameterSpec : JavaSpec, NamedSpec, JavaModifierContainer {
val name: String
val type: TypeRef<*>
val annotations: List<AnnotationRef>
val modifiers: Set<JavaModifier>
}构造:
// 简单参数
val paramSpec = JavaParameterSpec("value", JavaClassNames.STRING.ref())
// 带注解的参数
val annotatedParamSpec = JavaParameterSpec("id", JavaPrimitiveTypeNames.LONG.ref()) {
addAnnotation(ClassName("javax.annotation", "Nonnull").ref())
}
// final 参数
val finalParamSpec = JavaParameterSpec("config", someConfigType.ref()) {
addModifier(JavaModifier.FINAL)
}生成的输出:
String value
@Nonnull long id
final Config config收集 Java 访问修饰符和关键字。
public interface JavaModifierCollector<T> {
fun addModifier(modifier: JavaModifier): T
fun addModifiers(modifiers: Iterable<JavaModifier>): T
fun addModifiers(vararg modifiers: JavaModifier): T
}Java 修饰符:
- 访问:
PUBLIC、PROTECTED、PRIVATE - 继承:
ABSTRACT、FINAL、STATIC - 同步:
SYNCHRONIZED、VOLATILE - 本机:
NATIVE、STRICTFP、TRANSIENT - 密封:
SEALED、NON_SEALED(Java 17+)
收集静态初始化块(Java 特定)。
public interface StaticBlockCollector<T> {
fun addStaticBlock(format: String, vararg args: CodeArgumentPart): T
fun addStaticBlock(codeBlock: CodeValue): T
}用法:
classBuilder.addStaticBlock("""
System.out.println("类已加载");
initialize();
""".trimIndent())收集 Java 方法。
public interface JavaMethodCollector<T> {
fun addMethod(method: JavaMethodSpec): T
fun addMethods(methods: Iterable<JavaMethodSpec>): T
fun addMethods(vararg methods: JavaMethodSpec): T
}收集 Java 字段。
public interface JavaFieldCollector<T> {
fun addField(field: JavaFieldSpec): T
fun addFields(fields: Iterable<JavaFieldSpec>): T
fun addFields(vararg fields: JavaFieldSpec): T
}收集嵌套 Java 类型。
public interface JavaSubtypeCollector<T> {
fun addSubtype(subtype: JavaTypeSpec): T
fun addSubtypes(subtypes: Iterable<JavaTypeSpec>): T
fun addSubtypes(vararg subtypes: JavaTypeSpec): T
}CodeGentle 提供 DSL 和传统构建器模式:
// DSL 模式(推荐)
val spec = JavaSimpleTypeSpec(Kind.CLASS, "MyClass") {
addModifier(JavaModifier.PUBLIC)
addField(JavaFieldSpec("field", stringType) {
addModifier(JavaModifier.PRIVATE)
})
}
// 构建器模式
val spec = JavaSimpleTypeSpec.builder(Kind.CLASS, "MyClass")
.addModifier(JavaModifier.PUBLIC)
.addField(
JavaFieldSpec.builder("field", stringType)
.addModifier(JavaModifier.PRIVATE)
.build()
)
.build()每种规范类型都提供伴生对象方法用于构造:
// JavaMethodSpec 伴生
JavaMethodSpec.methodBuilder("methodName") // 常规方法
JavaMethodSpec.constructorBuilder() // 构造函数
JavaMethodSpec.mainBuilder() // main 方法
// JavaSimpleTypeSpec 伴生
JavaSimpleTypeSpec.builder(kind, name)val serviceClass = JavaSimpleTypeSpec(JavaTypeSpec.Kind.CLASS, "UserService") {
addModifier(JavaModifier.PUBLIC)
addDoc("管理用户的服务。")
// 添加接口
addSuperinterface(ClassName("com.example", "Service"))
// 私有字段
addField(JavaFieldSpec("repository", repositoryType) {
addModifier(JavaModifier.PRIVATE, JavaModifier.FINAL)
})
// 构造函数
addMethod(JavaMethodSpec {
addModifier(JavaModifier.PUBLIC)
addParameter(JavaParameterSpec("repository", repositoryType))
addCode("this.repository = repository;")
})
// 业务方法
addMethod(JavaMethodSpec("findUser") {
addModifier(JavaModifier.PUBLIC)
returns(userType.ref())
addParameter(JavaParameterSpec("id", JavaPrimitiveTypeNames.LONG.ref()))
addException(ClassName("java.sql", "SQLException").ref())
addCode("""
return repository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
""".trimIndent())
})
// 静态工厂方法
addMethod(JavaMethodSpec("create") {
addModifier(JavaModifier.PUBLIC, JavaModifier.STATIC)
returns(ClassName("com.example", "UserService").ref())
addParameter(JavaParameterSpec("repository", repositoryType))
addCode("return new UserService(repository);")
})
}val serviceInterface = JavaSimpleTypeSpec(JavaTypeSpec.Kind.INTERFACE, "Cacheable") {
addModifier(JavaModifier.PUBLIC)
addDoc("可缓存对象的接口。")
// 抽象方法
addMethod(JavaMethodSpec("getCacheKey") {
addModifier(JavaModifier.PUBLIC, JavaModifier.ABSTRACT)
returns(JavaClassNames.STRING.ref())
})
// 默认方法
addMethod(JavaMethodSpec("evictCache") {
addModifier(JavaModifier.PUBLIC, JavaModifier.DEFAULT)
addCode("""
String key = getCacheKey();
CacheManager.evict(key);
""".trimIndent())
})
// 静态方法
addMethod(JavaMethodSpec("clearAll") {
addModifier(JavaModifier.PUBLIC, JavaModifier.STATIC)
addCode("CacheManager.clear();")
})
}