2012-11-26 11 views
19

Chú thích có thể có kiểu trả về phức tạp, chẳng hạn như HashMap.Chú thích java có thể có kiểu trả về phức tạp như HashMap

Tôi đang tìm kiếm một cái gì đó như:

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface column { 
    public HashMap<String, String> table(); 
} 

vì vậy tôi có thể có một hằng số chú thích như (mã giả):

@column({table=(dbName, tableName), table=(dbName, tableName2)}) 
public static final String USER_ID = "userid"; 

Nếu Chú không cho phép bạn có phức tạp loại trả về, sau đó thực hành tốt cho loại trường hợp này?

+0

câu hỏi tuyệt vời .. –

Trả lời

48

Không, phần tử chú thích chỉ có thể là các loại nguyên thủy, Chuỗi, enum loại, Class, các chú thích khác hoặc các mảng bất kỳ trong số này. Cách tiêu biểu đại diện cho các loại công trình sẽ được tuyên bố một loại chú thích

public @interface TableMapping { 
    public String dbName(); 
    public String tableName(); 
} 

sau đó nói

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface column { 
    public TableMapping[] table(); 
} 

Và sử dụng các chú thích như

@column(table={ 
    @TableMapping(dbName="dbName", tableName="tableName"), 
    @TableMapping(dbName="db2", tableName="table2") 
}) 
public String userId = "userid"; 
+1

Đừng quên enums và các lớp –

+0

@ AleksanderBlomskøld điểm tốt, cảm ơn. –

+0

@IanRoberts Tôi đã làm một cái gì đó tương tự, nó kinda gây phiền nhiễu, nếu bạn sử dụng @ bảng chỉ, ngay cả một số cột chỉ có một TableMapping đã có bảng @ cùng với một @ TableMapping. Nếu bạn bắt đầu sử dụng bảng @ cho các trường có nhiều hơn một ánh xạ trong khi sử dụng @ TableMapping cho các cột chỉ có một ánh xạ. Nhưng trường hợp thứ hai sẽ có một phương pháp phức tạp hơn để lấy ví dụ. getColumnsInTableA(). – Shengjie

3

Một vài năm sau đó mang chúng tôi Java 8. Nó cung cấp một cách để lặp lại các chú thích của cùng một lớp.

Trong Java 8, bạn có thể khai báo chú thích được bao bọc hoàn toàn trong chú thích vùng chứa. Bạn khai báo là @Repeated(value=a_class) chú thích bạn muốn lặp lại. Khi bạn thêm nhiều phiên bản của chú thích có thể lặp lại, trình biên dịch sẽ tự động bao bọc các chú thích này trong chú thích vùng chứa a_class được chỉ định làm đối số cho @Repeated.

Nếu bạn khai báo:

@Retention(RetentionPolicy.RUNTIME) 
public @interface Columns { 
    Column[] value() default {}; 
} 

@Retention(RetentionPolicy.RUNTIME) 
@Repeatable(value = Columns.class) 
public @interface Column { 
    String dbName(); 
    String tableName(); 
} 

sau đó bạn có thể sử dụng chú thích nhiều lần có hoặc không có gói chúng trong chú thích khác, cả hai đều là tương đương:

@Column(dbName="db1", tableName="table1") 
@Column(dbName="db2", tableName="table2") 
public static final String USER_ID = "userid"; 

@Columns({ 
     @Column(dbName="db3", tableName="table3"), 
     @Column(dbName="db4", tableName="table4") 
}) 
public static final String LAST_NAME = "last name"; 

Các chú thích được lấy ra sử dụng getAnnotationsByType(class) trong cả hai trường hợp.

public static void main(String[] args) { 
    for(Field field : AnnotationsTest.class.getDeclaredFields()){ 
     System.out.println("Field: " + field.getName()); 
     Column[] columns = field.getAnnotationsByType(Column.class); 
     for(Column column : columns){ 
      System.out.println(" db: " + column.dbName() + " table: " + column.tableName()); 
     } 
     System.out.println(); 
    } 
} 

Nó nên đầu ra:

Field: USER_ID 
    db: db1 table: table1 
    db: db2 table: table2 

Field: LAST_NAME 
    db: db3 table: table3 
    db: db4 table: table4