パッケージjava.lang.classfile.attribute


パッケージjava.lang.classfile.attribute

java.lang.classfileライブラリのclassファイル属性を記述するインタフェースを提供します。

java.lang.classfile.attributeパッケージには、事前定義済の(JVMS 4.7)およびJDK固有の非標準属性(マッパーはAttributesで定義)など、特定のclassファイル属性を記述するインタフェースが含まれています。 このパッケージ・サマリーは、AttributeAttributedElementAttributeMapperCustomAttributeなど、このパッケージに存在しないclassファイル属性システムの概要を示します。

特に指定がないかぎり、nullまたはnull要素を含む配列またはコレクションを引数としてクラス・ファイルAPIクラスまたはインタフェースのコンストラクタまたはメソッドに渡すと、NullPointerExceptionがスローされます。

読取り属性

属性を取得する一般的な方法は、AttributedElementを使用することです。 それに加えて、多くの属性にはClassElementFieldElementMethodElement、またはCodeElementが実装されており、これらの属性は通常、特に指定されていないかぎり、ストリーミング・トラバーサルで囲んでいる要素がCompoundElementとして表示されるときに配信されます。

classファイルから読み取ると、属性は遅延的に膨張します。これらの属性の内容は解析を高速化するために評価されず、AttributeMapper.readAttribute(java.lang.classfile.AttributedElement, java.lang.classfile.ClassReader, int)からのユーザー定義属性も遅延する必要があります。 ユーザーの関心のあるコンテンツはオンデマンドで読み取ることができるため、ある属性のエラーによって他の属性へのアクセスが妨げられることはありません。

属性の内容は、元のclassファイルを厳密に表すために、定数プール・エントリで表されます。 これらのエントリは、それらを検証されたシンボリック記述子として表示するための変換メソッドを提供します。 属性の読取り速度にも影響する可能性がある定数プール・エントリの有効な読取りについては、java.lang.classfile.constantpoolを確認してください。 Deprecated注釈の存在を確認する次の例を参照してください:

private static final String DEPRECATED_DESC = Deprecated.class.descriptorString();

static boolean hasDeprecated(AttributedElement element) {
    var annotations = element.findAttribute(Attributes.runtimeVisibleAnnotations())
            .map(RuntimeVisibleAnnotationsAttribute::annotations)
            .orElse(List.of());
    for (var anno : annotations) {
        // equalsString reduces extra computations for raw UTF-8 entries
        if (anno.className().equalsString(DEPRECATED_DESC)) {
            return true;
        }
    }
    return false;
}

classファイルの解析が遅延しているため、構造的な破損が原因で属性自体から、または属性によって参照される一定のプール・エントリから、不正な形式のclassファイル・データを示すIllegalArgumentExceptionをメソッド起動時にスローできます。 注釈属性などの一部の属性は、JVMSごとに不正な形式である場合は、暗黙的に無視する必要があります。その結果、属性処理コードでは、このような属性で失敗を伝播するのではなく、IllegalArgumentExceptionを予測してスキップする必要があります。

属性の記述

ほとんどの属性は、ClassElementFieldElementMethodElementまたはCodeElementの少なくとも1つを実装しているため、これらの構造の一部として書き込まれるそれぞれのClassFileBuilderに送信できます。 属性は、1つの構造で「複数回表示される」できるかどうかを定義します。できない場合は、ビルダーに提供される最後の属性インスタンスが最終構造に書き込まれます。 BootstrapMethodsAttributeなどの一部の属性は、これらのインタフェースを実装しません。 これらは、各属性のモデリング・インタフェースで指定される他の方法で作成されます。 RecordComponentInfoの属性は、ファクトリ・メソッドを介して提供されます。

通常、属性ファクトリには2つのファクトリ・メソッド・セットがあります: 使用を表すシンボリック情報、および定数プール・エントリを受け入れるシンボリック情報を受け入れるもの。 ほとんどの場合、シンボリック・ファクトリは十分ですが、定数プール・エントリ・エントリは、classファイルの生成に対するファイングレイン制御に使用できます。詳細は、「定数プール・エントリの書き込み」を参照してください。

依存するデータが変更されない場合、多くの属性を一括コピーできます。この情報はAttributeMapper.stability()で公開され、各属性についてモデリング・インタフェースで文書化されます。 一括コピー機能により、classファイルの生成または変換が大幅に高速化されます。 また、ClassFile.AttributesProcessingOptionとともに、データを確認できない他のclassファイルから読み取られた属性が、現在構築中のclassファイルに対して有効であることは、削除される可能性があります。

Java Virtual Machine仕様を参照してください:
4.7 属性
導入されたバージョン:
24
関連項目: