Jenis apa yang dapat digunakan untuk anggota penjelasan Java?

238

Hari ini saya ingin membuat antarmuka anotasi pertama saya setelah dokumentasi ini dan saya mendapat kesalahan kompilator ini

Invalid type for annotation member":
public @interface MyAnnotation {
    Object myParameter;
    ^^^^^^
}

Jelas Objecttidak dapat digunakan sebagai jenis anggota penjelasan. Sayangnya saya tidak dapat menemukan informasi tentang jenis apa yang dapat digunakan secara umum.

Ini saya temukan menggunakan trial-and-error:

  • String → Valid
  • int → Valid
  • Integer → Tidak Valid (Mengejutkan)
  • String[] → Valid (Mengejutkan)
  • Object → Tidak Valid

Mungkin seseorang dapat menjelaskan jenis mana yang benar-benar diperbolehkan dan mengapa.

Daniel Rikowski
sumber
mungkin ini bervariasi berdasarkan anotasi - tolong tunjukkan kode yang Anda coba tulis.
djna
2
Ditambahkan ke pertanyaan. Tapi saya pikir itu tidak bervariasi.
Daniel Rikowski

Jawaban:

324

Ini ditentukan oleh bagian 9.6.1 dari JLS . Jenis anggota penjelasan harus salah satu dari:

  • primitif
  • Tali
  • sebuah Enum
  • Anotasi lain
  • Kelas
  • array dari salah satu di atas

Tampaknya memang membatasi, tetapi tidak diragukan lagi ada alasan untuk itu.

Perhatikan juga bahwa array multidimensi (mis. String[][]) Secara implisit dilarang oleh aturan di atas.

Susunan Kelas tidak diizinkan seperti yang dijelaskan dalam jawaban ini .

skaffman
sumber
33
Bagaimana cara menemukan halaman / dokumen tersebut? Saya bersumpah saya google setiap kali sebelum bertanya pada StackOverlow dan pada banyak pertanyaan Jawa seseorang memposting tautan ke JSL yang menjawab pertanyaan saya. Mengapa saya tidak menemukan halaman itu melalui Google ?!
Daniel Rikowski
10
JLS tidak terlalu ramah terhadap google. Anda hanya perlu tahu bahwa itu ada di sana.
skaffman
1
informasi yang sama juga tersedia dalam panduan anotasi di situs sun (menemukan googling): java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
wds
1
Ya, saya menemukan halaman itu juga, tetapi saya pasti melewatkan kalimat itu, tersembunyi di semua teks prosa itu. Saya telah mencari sesuatu yang lebih seperti tabel atau daftar.
Daniel Rikowski
13
Apa yang hilang dari daftar di atas adalah "Anotasi". Anda dapat memiliki anotasi yang berisi anotasi lain atau larik anotasi lain.
Matt
58

Saya setuju dengan Skaffman untuk Jenis yang tersedia.

Pembatasan tambahan: harus berupa konstanta waktu kompilasi .

Misalnya, berikut ini dilarang:

@MyAnnot("a" + myConstantStringMethod())
@MyAnnot(1 + myConstantIntMethod())
KLE
sumber
31

Juga jangan lupa bahwa anotasi itu sendiri dapat menjadi bagian dari definisi anotasi . Ini memungkinkan beberapa anotasi penjelasan sederhana - berguna dalam kasus di mana Anda ingin memiliki satu anotasi hadir berkali-kali.

Sebagai contoh:

@ComplexAnnotation({
    @SimpleAnnotation(a="...", b=3),
    @SimpleAnnotation(a="...", b=3),
    @SimpleAnnotation(a="...", b=3)
})
public Object foo() {...}

di mana SimpleAnnotationadalah

@Target(ElementType.METHOD)
public @interface SimpleAnnotation {
    public String a();
    public int b();
)

dan ComplexAnnotationadalah

@Target(ElementType.METHOD)
public @interface ComplexAnnotation {
    public SimpleAnnotation[] value() default {};
)

Contoh diambil dari: http://web.archive.org/web/20131216093805/https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

(URL asli: https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations )

fikovnik
sumber
6
Dengan Java 8 @Repeatable, ini tidak diperlukan lagi.
Mordechai
11

Konsep anotasi sangat cocok dengan desain proyek saya, sampai saya menyadari Anda tidak dapat memiliki tipe data kompleks dalam anotasi. Saya mengatasinya dengan menggunakan kelas apa yang ingin saya instantiate daripada objek instantiated kelas itu. Itu tidak sempurna, tetapi java jarang.

@interface Decorated { Class<? extends PropertyDecorator> decorator() }

interface PropertyDecorator { String decorate(String value) }

class TitleCaseDecorator implements PropertyDecorator {
    String decorate(String value)
}

class Person {
    @Decorated(decorator = TitleCaseDecorator.class)
    String name
}
Josh
sumber