2017-04-17 2 views
3

Javaの注釈の宣言の中にフィールドと列挙型を宣言することは可能です。たとえば、javacのは、これをコンパイルします。アノテーション宣言内で列挙型とフィールドを定義する意味はなんですか?

@interface ClassPreamble { 
    public enum AnEnum { 
     Value; 
    } 
    String aField = ""; 

    String author(); 
    String date(); 
    String currentRevision() default ""; 
    String lastModified() default "N/A"; 
    String lastModifiedBy() default "N/A"; 
    // Note use of array 
    String[] reviewers(); 
} 

注釈宣言内の列挙型とフィールドを定義の意味/有用性とは何ですか?

おかげ

+0

:例えば、一つは注釈タイプと一緒に使用するためのネストされた列挙型を宣言することを選択するかもしれません[official docs](https://docs.oracle.com/javase/tutorial/java/annotations/declaring.html)を参照してください。 –

+0

@OliverCharlesworth私の質問をよくお読みください。注釈がどのように役立つかを知っています。私は、アノテーション宣言の中でフィールドと列挙型を定義することがどれほど有用なのか分かりません。 – mljrg

+0

はい、そのリンクが例を挙げています。 –

答えて

1

Javaアノテーションは、単なる継承するインターフェイスですjava.lang.annotation.Annotation(*)、およびある程度コンパイラによって特別に扱われますが、コンパイラはインターフェース内で合法であるものは何でもやってからあなたを防ぐことはできません。それは役に立ちます(この答えの一番下にあるJLSの例を参照してください)。

(*)を手動Annotationを拡張するインタフェースは注釈型(ソース:javadocAnnotation.java用)定義されていませんが

あなたの注釈ClassPreambleを効果的interface ClassPreamble extends java.lang.annotation.Annotation(ご覧になると、それを逆コンパイル)です。

インターフェイス内で列挙型を宣言することは正当です。 インターフェイスでフィールドを宣言することは正当です。暗黙的にpublic static finalになります。

$ cat Funny.java 
interface Funny { 
    public enum AnEnum { One, Two } 
    String aField = ""; 
} 

$ javac Funny.java 

$ javap -c Funny.class 
Compiled from "Funny.java" 
interface Funny extends java.lang.annotation.Annotation { 
    public static final java.lang.String aField; 

} 

$ javap -c Funny\$AnEnum.class | head 
Compiled from "Funny.java" 
public final class Funny$AnEnum extends java.lang.Enum<Funny$AnEnum> { 
    public static final Funny$AnEnum One; 

    public static final Funny$AnEnum Two; 

    public static Funny$AnEnum[] values(); 
    Code: 
     0: getstatic  #1     // Field $VALUES:[LFunny$AnEnum; 
     3: invokevirtual #2     // Method "[LFunny$AnEnum;".clone:()Ljava/lang/Object; 
... 

"このような構成要素の意味は何ですか?"とはよく分かりません。私はそれがデザインの選択肢としてこのように実装されたと思います。注釈の内容は、JVMが扱う方法を知っているインターフェースのバイトコードとしてエンコードされているので、JVM自体をあまりにも大きく変更する必要はありません、それはコンパイル時と実行時に必要な機能を許可し、害を及ぼしません(またはそれをしますか?)。

編集:(インターフェース約9章に属する)Java Language Specification section 9.6 about annotationsから2点の抽出:

注釈型の宣言は、新しい注釈タイプ、インターフェイスタイプの特別な種類を指定します。注釈型宣言を通常のインタフェース宣言と区別するために、キーワードインタフェースの前にアットマーク(@)が付いています。

[...]

注釈型宣言の文法はメソッド宣言に加えて他の要素宣言を可能にします。これは、例えば、に説明され

@interface Quality { 
    enum Level { BAD, INDIFFERENT, GOOD } 
    Level value(); 
} 
+0

ええ、インターフェースコンパイラのインフラストラクチャが注釈をサポートするためにハッキングされているようで、ハッキングは不完全なままです。例えば、Level値()のデフォルトのINDIFFERENTを実行すると、 'Quality'はコンパイルエラーで失敗します。これは完全に有効であるはずです。私は、このような注釈宣言の例を見たことがないので、私は興味がありました。私はすでにこれが "ハッキング"のケースであると疑っていて、あなたの答えを受け入れるでしょう。 – mljrg

+0

'レベル値(デフォルト)Level.INDIFFERENT;は正解で受け入れられました –

+0

OK、試してみるのを忘れました。それを知ってよかった! – mljrg

関連する問題