Những loại nào có thể được sử dụng cho các thành viên chú thích Java?


238

Hôm nay tôi muốn tạo giao diện chú thích đầu tiên của mình theo tài liệu này và tôi đã gặp lỗi trình biên dịch này

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

Rõ ràng Objectkhông thể được sử dụng như là một loại thành viên chú thích. Thật không may, tôi không thể tìm thấy bất kỳ thông tin về loại có thể được sử dụng nói chung.

Điều này tôi phát hiện ra bằng cách sử dụng thử và lỗi:

  • String → Hợp lệ
  • int → Hợp lệ
  • Integer → Không hợp lệ (Đáng ngạc nhiên)
  • String[] → Hợp lệ (Đáng ngạc nhiên)
  • Object → Không hợp lệ

Có lẽ ai đó có thể làm sáng tỏ loại nào thực sự được phép và tại sao.


có thể nó thay đổi theo chú thích - vui lòng hiển thị mã bạn đang cố viết.
djna

2
Thêm vào câu hỏi. Nhưng tôi không nghĩ nó thay đổi.
Daniel Rikowski

Câu trả lời:


324

Nó được chỉ định bởi mục 9.6.1 của JLS . Các loại thành viên chú thích phải là một trong:

  • nguyên thủy
  • Chuỗi
  • một Enum
  • chú thích khác
  • Lớp học
  • một mảng của bất kỳ ở trên

Nó có vẻ hạn chế, nhưng không có nghi ngờ gì có lý do cho nó.

Cũng lưu ý rằng các mảng đa chiều (ví dụ String[][]) bị cấm theo quy tắc trên.

Mảng của lớp không được phép như mô tả trong câu trả lời này .


33
Làm thế nào để một người tìm thấy những trang / tài liệu? Tôi thề tôi google mọi lúc trước khi hỏi trên StackOverlow và trên nhiều câu hỏi Java có ai đó gửi một liên kết đến JSL để trả lời câu hỏi của tôi. Tại sao tôi không tìm thấy những trang đó qua Google?!
Daniel Rikowski

10
JLS không thân thiện với google. Bạn chỉ cần biết rằng nó ở đó.
skaffman

1
thông tin tương tự cũng có sẵn trong hướng dẫn chú thích trên trang web của mặt trời (đã tìm thấy điều đó): java.sun.com/j2se/1.5.0/docs/guide/lingu/annotations.html
wds

1
Vâng, tôi cũng tìm thấy trang đó, nhưng tôi đã bỏ lỡ câu đó, ẩn trong tất cả các văn bản văn xuôi. Tôi đã tìm kiếm một cái gì đó nhiều bảng hoặc giống như danh sách.
Daniel Rikowski

13
Điều còn thiếu trong danh sách trên là "Chú thích". Bạn có thể có một chú thích chứa chú thích khác hoặc một mảng của chú thích khác.
Matt

58

Tôi đồng ý với Skaffman cho các loại có sẵn.

Hạn chế bổ sung: nó phải là hằng số thời gian biên dịch .

Ví dụ: những điều sau đây bị cấm:

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

31

Cũng đừng quên rằng chính các chú thích có thể là một phần của định nghĩa chú thích . Điều này cho phép một số lồng chú thích đơn giản - tiện dụng trong trường hợp bạn muốn có một chú thích hiện diện nhiều lần.

Ví dụ:

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

nơi SimpleAnnotation

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

ComplexAnnotation

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

Ví dụ được lấy từ: http://web.archive.org/web/20131216093805/https://bloss.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

(URL gốc: https://bloss.oracle.com/toddfast/entry/creating_nested_complex_java_annotations )


6
Với Java 8 @Repeatable, điều này không còn cần thiết nữa.
Mordechai

11

Khái niệm chú thích rất phù hợp với thiết kế dự án của tôi, cho đến khi tôi nhận ra bạn không thể có các kiểu dữ liệu phức tạp trong chú thích. Tôi đã khắc phục nó bằng cách sử dụng lớp của những gì tôi muốn khởi tạo thay vì một đối tượng khởi tạo của lớp đó. Nó không hoàn hảo, nhưng java hiếm khi.

@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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.