Dagger 2具有编译时验证,那么为什么范围注释有RUNTIME
保留?为什么在运行时需要它们?
答案 0 :(得分:7)
虽然我不确定,但我猜测Scopes必然具有运行时保留期,因为JSR 330's @Scope
要求范围具有运行时保留。 (@Qualifier
具有相同的限制。)Dagger 1和Dagger 2都宣传JSR-330兼容性,并且(在评论中提到David)有很多运行时依赖注入解决方案,绝对需要运行时 - 保留范围注释。
特别是对于Dagger,我无法想象为什么他们实际上也会在运行时被读取,尽管我想一些外部库可以使用注释。
这不一定是遗留问题或其他问题:许多DI系统在运行时配置并需要注释。 Dagger值得注意的是它没有,但规范并没有以允许运行时保留为可选的方式编写。这使得应用程序开发人员可以将Dagger替换为Guice或Spring等不同的JSR330框架,并使库开发人员能够使与DI兼容的工具或框架与编译时配置或运行时配置无关。该规范的清晰度(即没有实现选项)和灵活性(编译时或运行时)似乎值得花费不必要的注释保留和学习成本。
但是, 可能是大型Android应用中的一个问题,因为Android keeps runtime-annotated classes in the main dex by default;如果带注释的类位于辅助dex中,则旧版本的Android无法加载运行时注释。有关详细信息,请参阅this bug中链接的keepRuntimeAnnotatedClasses
docs。虽然你可以认为这是一个Dagger问题,因为Dagger适用于大型Android应用程序,但更多的是Android注释处理的错误,为此Dagger需要偏离JSR-330规范才能自行处理。