86

「属性値は定数でなければなりません」というエラーが表示されるのはなぜですか。null定数じゃないの???

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SomeInterface {
    Class<? extends Foo> bar() default null;// this doesn't compile
}
4

7 に答える 7

69

これを試して

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SomeInterface {
    Class bar() default void.class;
}

新しいクラスを必要とせず、Java ではすでに何の意味もないキーワードになっています。

于 2013-04-24T19:43:58.937 に答える
55

JLS はこれについて非常にあいまいですが、これは違法であるように思われます。

私は自分の記憶をかき乱し、注釈への Class 属性を持つ既存の注釈を考えてみました。そして、JAXB API からこれを思い出しました。

@Retention(RUNTIME) @Target({PACKAGE,FIELD,METHOD,TYPE,PARAMETER})        
public @interface XmlJavaTypeAdapter {
    Class type() default DEFAULT.class;

    static final class DEFAULT {}    
}

null と同等のものを保持するためにダミーの静的クラスを定義する必要があったことがわかります。

不快。

于 2009-07-24T14:43:58.917 に答える
11

やり方は他にもあるようです。

私もこれは好きではありませんが、うまくいくかもしれません。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SomeInterface {
    Class<? extends Foo>[] bar() default {};
}

したがって、基本的には代わりに空の配列を作成します。これはデフォルト値を許可しているようです。

于 2014-09-02T13:02:22.187 に答える
2

他の人が言ったように、Java では null は有効なデフォルト値ではないという規則があります。

フィールドが持つことができる値の数が限られている場合、これを回避するための 1 つのオプションは、フィールド タイプを、それ自体が null へのマッピングを含むカスタム列挙型にすることです。たとえば、デフォルトの null が必要な次の注釈があるとします。

public @interface MyAnnotation {
   Class<?> value() default null;
}

私たちが確立したように、これは許可されていません。代わりにできることは、列挙型を定義することです。

public enum MyClassEnum {
    NULL(null),
    MY_CLASS1(MyClass1.class),
    MY_CLASS2(MyClass2.class),
    ;

    public final Class<?> myClass;

    MyClassEnum(Class<?> aClass) {
        myClass = aClass;
    }
}

注釈を次のように変更します。

public @interface MyAnnotation {
  MyClassEnum value() default MyClassEnum.NULL;
}

これの主な欠点 (考えられる値を列挙する必要があることは別として) は、値を列挙型でラップしたため、列挙型でプロパティ/ゲッターを呼び出して値を取得する必要があることです。

于 2019-11-07T04:57:52.543 に答える