面试题答案
一键面试- 定义注解:
- 使用
annotation
关键字定义注解。例如,假设要为某个数据类生成特定的辅助代码,可以这样定义注解:
@Retention(AnnotationRetention.SOURCE) @Target(AnnotationTarget.CLASS) annotation class GenerateHelperCode
@Retention(AnnotationRetention.SOURCE)
表示该注解仅在源码阶段保留,编译后不会存在于字节码中。@Target(AnnotationTarget.CLASS)
表示该注解只能应用在类上。
- 使用
- 处理器识别目标类并生成代码:
- 创建一个继承自
AbstractProcessor
的注解处理器类。 - 在
init
块中注册支持的注解和源版本:
init { supportedAnnotationTypes = setOf(GenerateHelperCode::class.java.canonicalName) supportedSourceVersion = SourceVersion.latestSupported() }
- 重写
process
方法,在该方法中:- 获取所有被注解的元素(即目标类):
val elements = roundEnv.getElementsAnnotatedWith(GenerateHelperCode::class.java)
- 遍历这些元素,为每个元素生成代码。可以使用
JavaPoet
库来生成Java代码(因为Kotlin注解处理器在Java环境下运行)。例如:
for (element in elements) { val className = element.simpleName.toString() val packageName = processingEnv.elementUtils.getPackageOf(element).qualifiedName.toString() val generatedClassName = className + "Helper" val typeSpec = TypeSpec.classBuilder(generatedClassName) .addModifiers(Modifier.PUBLIC) .build() val javaFile = JavaFile.builder(packageName, typeSpec) .build() javaFile.writeTo(processingEnv.filer) }
- 创建一个继承自
- 处理生成代码中的依赖关系:
- 如果生成的代码依赖其他类,确保这些类在编译时可访问。
- 对于内部项目依赖,可以通过在项目的
build.gradle
文件中添加相应的模块依赖。例如,如果生成的代码依赖项目中的common
模块:
dependencies { implementation project(':common') }
- 对于外部依赖,同样在
build.gradle
中添加依赖。例如,使用gson
库:
dependencies { implementation 'com.google.code.gson:gson:2.8.6' }
- 在生成代码时,使用正确的导入语句引入依赖的类。例如,如果依赖
gson
的Gson
类:
val typeSpec = TypeSpec.classBuilder(generatedClassName) .addModifiers(Modifier.PUBLIC) .addImport("com.google.gson.Gson") .addField(Gson::class.java, "gson", Modifier.PRIVATE) .build()