9

私は Kotlin の注釈プロセッサに取り組んでおり、処理された要素は Java にあるため、?代わりに@Nullable注釈を使用して nullables を受け取ることはありません。それで問題ありませんが、型や高次関数で null パラメータを受け取るという問題に直面しています。 、通常のパラメーターの場合。

var someNullField: String? = "" 

私はその注釈java.lang.Stringでプロセスで受け取ります。@org.jetbrains.annotations.Nullable

しかしList<String?>、たとえばjava.util.List<java.lang.String>、タイプ引数ではなくメイン要素にない注釈なしで私を返します。これにより、不明な null 許容状態が発生します。

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()}")
            }
}

すべての助けをいただければ幸いです。

4

1 に答える 1

6

少し必要な歴史: Java 6 (Mirror API が公開されたとき) の時点で、Java アノテーションは何にも使用できませんでしたが、リフレクションを介してアクセスできる同じ種類の最上位要素に使用できました。クラス、メソッド、およびフィールドに注釈を付けることができましたが、型引数 ( List<String>) またはローカル変数 ( String value = ...) に注釈を付けることができませんでした。Sun/Oracle のエンジニアはその制限を認識しており、Java 8 ではいわゆる「型注釈」が生まれました。

型注釈は、ローカル変数の型、配列コンポーネントの型、型変数の型、さらには戻り値の型など、あらゆるを対象にすることができます(後の注釈は同様に配置されますが、メソッドの古い学校の注釈とは異なります!)。型注釈は、新しい値ElementType#TYPE_USEを介して作成されます。@Target

Kotlin が書くとき

List<String?>

それは本当に意味します

List<@Nullable String>

これは、「null 許容 String 要素のリスト」として読み取ることができます。

自体がターゲットにされているため、元の型を調べて注釈を取得する必要があります(TypeMirror消去またはキャプチャされた TypeMirror を気にしないでください。注釈を保持するためのソース コードへの接続が十分ではありません)。偶然にも、Mirror API がリファクタリングされ、その結果、新しいインターフェイスAnnotatedConstructが作成され、便利なことに TypeMirror がその子孫になりました。


ここで悪いニュースがあります。Java 8 がリリースされるまでに、型注釈の検査のサポートは明らかに本番環境に対応していないため、解体されました。JSR は、「TypeMirror#getAnnotationMirrors」が何も返さないことを意味するように書き直されました。

パブリック API から削除された一部のサポートは、Oracle のベンダー固有のTree API (javac でのみサポート) を介して引き続き利用できます。Tree#getTypeMirror によって返される TypeMirror には、予想どおりの方法で注釈が含まれている場合があります。しかし、これにはバグがあるため、一連のハックによってのみアノテーションを取得でき、最終的に、これは常に機能するとは限りません (ネストされた型引数の場合など)。その方向の研究については、この質問を参照してください。

その混乱の修正は Java 9 にマージされました。まだテストしていませんが、TypeMirror#getAnnotationMirrors が最終的に機能するようです。この修正を古い Java バージョンにバックポートする予定はありません。

于 2017-08-20T07:14:13.300 に答える