web-dev-qa-db-ja.com

定数javaから注釈に値を提供する方法

注釈とそのパラメーターはコンパイル時に解決されるため、これはJavaでは不可能だと考えています。私は次のようなインターフェースを持っています、

public interface FieldValues {
   String[] FIELD1 = new String[]{"value1", "value2"};
}

そして別のクラスとして、

@SomeAnnotation(locations = {"value1", "value2"})
public class MyClass {
   ....
}

私は多くのクラスを注釈でマークし、代わりに使用したいすべての注釈で文字列を指定することを避けることができるかどうかを知りたい

@SomeAnnotation(locations = FieldValues.FIELD1)
public class MyClass {
   ....
}

ただし、これにより、注釈値が配列初期化子などである必要があるなどのコンパイルエラーが発生します。誰かがString定数またはString []定数を使用して注釈に値を提供する方法を知っていますか?

130
Kannan Ekanath

コンパイル定数 プリミティブと文字列のみ

15.28。定数式

コンパイル時定数式は、プリミティブ型の値、または突然完了せず、次のみを使用して構成される文字列の値を示す式です。

  • プリミティブ型のリテラルとString型のリテラル
  • プリミティブ型にキャストし、String型にキャストします
  • [...]演算子[...]
  • 含まれている式が定数式である括弧で囲まれた式。
  • 定数変数を参照する単純な名前。
  • フォームの修飾名TypeName定数変数を参照する識別子

実際、Javaには、配列内の項目を保護する方法はありません。実行時には、誰かがいつでもFieldValues.FIELD1[0]="value3"を実行できます。そのため、より深く見た場合、配列は実際には一定になりません。

115
irreputable

定数(つまり、静的な最終変数)を注釈のパラメーターとして使用できます。簡単な例として、私はこのようなものをかなり頻繁に使用します:

import org.junit.Test;
import static org.junit.Assert.*;

public class MyTestClass
{
    private static final int TEST_TIMEOUT = 60000; // one minute per test

    @Test(timeout=TEST_TIMEOUT)
    public void testJDK()
    {
        assertTrue("Something is very wrong", Boolean.TRUE);
    }
}

TEST_TIMEOUT定数をアノテーションに直接渡すことができることに注意してください。

ちなみに、配列でこれを試したことは一度もないので、Java変数と比較して、配列が注釈パラメーターとして表される方法にわずかな違いがある問題に遭遇するかもしれません。しかし、質問の他の部分に関しては、問題なく定数Stringを確実に使用できます。

編集:私はちょうど文字列配列でこれを試しましたが、あなたが言及した問題に遭遇しませんでした-しかし、コンパイラdid配列にもかかわらず「属性値は一定でなければならない」と教えてくださいpublic static final String[]として定義されます。おそらく、配列が可変であるという事実が気に入らないのでしょうか?うーん...

34
Andrzej Doyle

この例では、配列を提供していません。以下は正常にコンパイルされます:

   public @interface SampleAnnotation {
        String[] sampleValues();
    }

    public class Values {
        public static final String v1 = "A";
        public static final String v2 = "B";

        @SampleAnnotation(sampleValues = { v1, v2 })
        public void foo() {
        }
    }
10
Steve B.

誰かがString定数またはString []定数を使用して注釈に値を提供する方法を知っていますか?

残念ながら、配列でこれを行うことはできません。非配列変数では、値は最終的な静的でなければなりません。

7
Kevin

アノテーションとそのパラメーターはコンパイル時に解決されるため、Javaではこれが不可能かもしれないと考えています。

Seam 2 http://seamframework.org/ を使用すると、二重引用符で囲まれた式言語を使用して、実行時に注釈パラメーターを解決できました。

Seam 3では、この機能はSeam Solderモジュールです http://seamframework.org/Seam3/Solder

5
jorgwel