自定义Gradle Task如何通过Kotlin委托实现?
问题解答
你尝试的这种直接在类头使用Kotlin接口委托的方式不可行,报错原因是Kotlin的类初始化顺序限制:类声明中的接口委托会在类成员属性之前被处理,此时sourceFiles作为类内部的抽象属性还未被声明,编译器无法识别它。
为什么不能这么做
Kotlin在初始化类时,会按以下顺序执行:
- 初始化父类(这里是
DefaultTask) - 处理类头的接口委托逻辑
- 初始化类内部的成员属性(包括
sourceFiles)
所以在类头写ConfigurableFileCollection by sourceFiles时,sourceFiles还不存在,自然会报“未定义”的错误。
可行的简化方案
方案一:继承Gradle的SourceTask(推荐)
Gradle提供了SourceTask基类,它已经实现了CopySourceSpec接口,并且自带了source属性,你只需要继承它并配置属性注解即可,无需手动实现from方法:
@CacheableTask abstract class FooTask : SourceTask() { @get:InputFiles @get:Optional @get:SkipWhenEmpty @get:IgnoreEmptyDirectories @get:PathSensitive(PathSensitivity.RELATIVE) override val source: ConfigurableFileCollection = super.source @TaskAction fun canonize() { val sourceFileTree = source.asFileTree // 执行你的逻辑 } }
方案二:保留手动实现(如果必须继承DefaultTask)
如果因为某些原因不能继承SourceTask,那只能像你最初的代码那样手动实现CopySourceSpec的方法,这种方式虽然繁琐,但能保证逻辑正常运行——因为Gradle的抽象属性是在运行时由框架注入的,编译期无法作为接口委托的实例使用,没有其他更简洁的Kotlin委托方式可以替代。
内容的提问来源于stack exchange,提问作者phreed
相关产品推荐
相关产品推荐

