java - kotlin 注释处理器中的可空类型

标签 java annotations kotlin annotation-processing kapt

我正在为 Kotlin 开发注释处理器,因为处理的元素是在 Java 中,所以我没有收到可以为 ? 的空值。而是使用 @Nullable注释,这很好,但是对于普通参数,我遇到了在类型和高阶函数中接收空参数的问题。

var someNullField: String? = "" 

我将收到 java.lang.String正在处理 @org.jetbrains.annotations.Nullable在其注释中。

但是List<String?>例如将返回我java.util.List<java.lang.String>没有任何注释,不在主元素中,不在类型参数中,导致未知的可空性状态

我尝试使用 javax.lang.model.util.Types找到某种结果,但什么也没有。

我现在使用的一些代码:

val utils = processingEnvironment.typeUtils
val type = fieldElement.asType()
if (type is DeclaredType) {
    val typeElement = utils.asElement(type)
    type.typeArguments
            .forEach {
                //Trying different ways and just printing for possible results
                val capture = utils.capture(it)
                val erasure = utils.erasure(it)
                val element = utils.asElement(it)
                printMessage("element: $element isNullable: ${element.isNullable()} isNotNull: ${element.isNotNull()}\ncapture: $capture isNullable: ${capture.isNullable()} isNotNull: ${capture.isNotNull()}\nerasure: $erasure isNullable: ${erasure.isNullable()} isNotNull: ${erasure.isNotNull()}")
            }
}

我们将不胜感激。

最佳答案

一些必要的历史:从 Java 6 开始(当 Mirror API 公开时)Java 注释不能用于任何东西,只能用于相同类型的顶级元素,可通过反射访问。您可以注释类、方法和字段,但不能注释类型参数 ( List<String> ) 或局部变量 ( String value = ... )。 Sun/Oracle 工程师已经承认了这个限制,并且在 Java 8 中诞生了所谓的“类型注释”。

类型注解可以针对任何type:type局部变量,数组组件类型,类型变量type 甚至是返回类型(后面的注解也是类似的,但与方法上的老式注解不同!)。类型注释是通过新的 @Target 创建的值:ElementType#TYPE_USE .

当 Kotlin 人写作时

List<String?>

真的是这样

List<@Nullable String>

可以读作:“可空字符串元素列表”。

由于 type 本身就是目标,因此您应该通过检查它的原始 TypeMirror 来获得注释。 (不要打扰已删除或捕获的 TypeMirror,它们与源代码的连接不足以保留注释)。巧合的是,镜像 API 被重构,产生了新的接口(interface) AnnotatedConstruct , 并且方便地将 TypeMirror 制作成它的后代。


现在有个坏消息:到 Java 8 发布时,对检查类型注释的支持显然还没有为生产做好准备,所以它被淘汰了。 JSR 已被重写以暗示“TypeMirror#getAnnotationMirrors”应该什么都不返回。

从公共(public) API 中删除的部分支持仍可通过 Oracle 的特定供应商 Tree API 获得(仅在 javac 中支持)。 Tree#getTypeMirror 返回的 TypeMirror 可能包含您期望的注释。但由于它有问题,您只能通过一系列 hack 获得注释,最终,这不会在任何时候都有效(例如在嵌套类型参数的情况下)。见 this question进行该方向的一些研究。

The fix因为那个烂摊子在 Java 9 中被合并了。我还没有测试过,但看起来 TypeMirror#getAnnotationMirrors 最终可能会起作用。没有计划将修复程序向后移植到较旧的 Java 版本。

关于java - kotlin 注释处理器中的可空类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45775825/

相关文章:

java - 计算出混合字符的校验和

java - 我可以在 MVC Controller 方法中在方法级别发送 java 注释,将 http 请求作为参数吗?

java - Guice Multibinder 用于具有特定值的注释

kotlin - 在扩展 Parceable 密封类的对象上使用 android-extensions 的 Parcelize 注释

android - 在 Kotlin 中以编程方式更改语言环境

java - 无法通过Java代码执行java -jar命令

java - Spring Web Flow 可以在非 UI 上下文中使用吗?

java - fragment 内的非法封闭实例

android - 如何使用 Kotlin、Coroutines、ViewModel、LiveData 处理查询方法的返回类型 room

android - 由 : rx. 异常引起。MissingBackpressureException