ประเภทใดที่สามารถใช้สำหรับสมาชิกคำอธิบายประกอบ Java?


238

วันนี้ฉันต้องการที่จะสร้างอินเตอร์เฟซคำอธิบายประกอบแรกของฉันตามเอกสารนี้และฉันได้รับข้อผิดพลาดของคอมไพเลอร์นี้

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

แน่นอนObjectไม่สามารถใช้เป็นประเภทของสมาชิกคำอธิบายประกอบ น่าเสียดายที่ฉันไม่พบข้อมูลใด ๆ ที่สามารถใช้งานทั่วไปได้

ฉันพบสิ่งนี้โดยใช้การทดลองและข้อผิดพลาด:

  • String →ถูกต้อง
  • int →ถูกต้อง
  • Integer →ไม่ถูกต้อง (น่าแปลกใจ)
  • String[] →ใช้ได้ (น่าแปลกใจ)
  • Object →ไม่ถูกต้อง

บางทีใครบางคนสามารถหลั่งน้ำตาแสงที่อนุญาตประเภทจริงและทำไม


อาจแตกต่างกันไปตามคำอธิบายประกอบ - โปรดแสดงรหัสที่คุณพยายามเขียน
djna

2
เพิ่มไปยังคำถาม แต่ฉันไม่คิดว่ามันจะแตกต่างกัน
Daniel Rikowski

คำตอบ:


324

มันถูกกำหนดไว้ในส่วนของ 9.6.1 JLS ประเภทสมาชิกคำอธิบายประกอบต้องเป็นหนึ่งใน:

  • ดั้งเดิม
  • เชือก
  • Enum
  • คำอธิบายประกอบอื่น
  • ชั้น
  • อาร์เรย์ใด ๆ ข้างต้น

ดูเหมือนจะเข้มงวด แต่ไม่ต้องสงสัยเลยว่ามีเหตุผล

โปรดทราบว่าอาร์เรย์หลายมิติ (เช่น String[][] ) ถูกห้ามโดยนัยตามกฎข้างต้น

ไม่อนุญาตให้ใช้อาร์เรย์ของคลาสตามที่อธิบายไว้ในคำตอบนี้


33
จะพบหน้า / เอกสารเหล่านั้นได้อย่างไร ฉันสาบานว่าฉัน google ทุกครั้งก่อนที่จะถามใน StackOverlow และคำถาม Java หลายคนโพสต์ลิงก์ไปยัง JSL ที่ตอบคำถามของฉัน ทำไมฉันไม่พบหน้าเหล่านั้นผ่านทาง Google!
Daniel Rikowski

10
JLS นั้นไม่ค่อยเป็นมิตรกับ Google คุณแค่ต้องรู้ว่ามันอยู่ตรงนั้น
skaffman

1
ข้อมูลเดียวกันนี้ยังมีอยู่ในคู่มือคำอธิบายประกอบบนไซต์ของ sun (พบว่า googling): java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
wds

1
ใช่ฉันพบหน้านั้นด้วย แต่ฉันต้องพลาดประโยคนั้นซึ่งซ่อนอยู่ในข้อความร้อยแก้วทั้งหมด ฉันค้นหาตารางหรือรายการที่คล้ายกันมากกว่านี้
Daniel Rikowski

13
สิ่งที่หายไปจากรายการด้านบนคือ "คำอธิบายประกอบ" คุณสามารถมีคำอธิบายประกอบที่มีคำอธิบายประกอบอื่นหรืออาร์เรย์ของคำอธิบายประกอบอื่น
Matt

58

ฉันเห็นด้วยกับ Skaffman สำหรับประเภทที่มีให้

ข้อ จำกัด เพิ่มเติม: มันจะต้องมีค่าคงที่เวลารวบรวม

ตัวอย่างเช่นสิ่งต่อไปนี้เป็นสิ่งต้องห้าม:

@MyAnnot("a" + myConstantStringMethod())
@MyAnnot(1 + myConstantIntMethod())

31

อย่าลืมว่าคำอธิบายประกอบนั้นสามารถเป็นส่วนหนึ่งของคำอธิบายประกอบได้ได้ วิธีนี้ช่วยให้การซ้อนคำอธิบายประกอบง่าย - มีประโยชน์ในกรณีที่คุณต้องการให้มีคำอธิบายประกอบหนึ่งรายการแสดงหลายครั้ง

ตัวอย่างเช่น:

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

ที่SimpleAnnotationเป็น

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

และComplexAnnotationเป็น

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

ตัวอย่างที่นำมาจาก: http://web.archive.org/web/20131216093805/https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

(URL เดิม: https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations )


6
ด้วย Java 8 @Repeatableสิ่งนี้ไม่จำเป็นอีกต่อไป
Mordechai

11

แนวคิดของคำอธิบายประกอบเหมาะสมกับการออกแบบโครงการของฉันจริง ๆ จนกระทั่งฉันรู้ว่าคุณไม่มีประเภทข้อมูลที่ซับซ้อนในการเพิ่มความคิดเห็น ฉันได้รอบมันโดยใช้คลาสของสิ่งที่ฉันต้องการสร้างอินสแตนซ์แทนที่จะเป็นวัตถุที่สร้างอินสแตนซ์ของคลาสนั้น มันไม่สมบูรณ์ แต่จาวาไม่ค่อยมี

@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
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.