2009-04-10 59 views
15

tôi đã tạo ra chú thích đơn giản trong JavaJava chú thích

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface Column { 
    String columnName(); 
} 

và lớp

public class Table { 

    @Column(columnName = "id") 
    private int colId; 

    @Column(columnName = "name") 
    private String colName; 

    private int noAnnotationHere; 

    public Table(int colId, String colName, int noAnnotationHere) { 
     this.colId = colId; 
     this.colName = colName; 
     this.noAnnotationHere = noAnnotationHere; 
    } 
} 

tôi cần để lặp qua tất cả các lĩnh vực, được chú thích với Column và nhận têngiá trị của trường và chú thích. Nhưng tôi gặp vấn đề với việc nhận được giá trị của mỗi trường, vì tất cả chúng đều khác nhau kiểu dữ liệu.

Có bất kỳ điều gì sẽ trả lại tập hợp các trường có một số chú thích nhất định không? Tôi đã làm điều đó với mã này, nhưng tôi không nghĩ rằng sự phản chiếu là cách tốt để giải quyết nó.

Table table = new Table(1, "test", 2); 

for (Field field : table.getClass().getDeclaredFields()) { 
    Column col; 
    // check if field has annotation 
    if ((col = field.getAnnotation(Column.class)) != null) { 
     String log = "colname: " + col.columnName() + "\n"; 
     log += "field name: " + field.getName() + "\n\n"; 

     // here i don't know how to get value of field, since all get methods 
     // are type specific 

     System.out.println(log); 
    } 
} 

Tôi có phải quấn mọi lĩnh vực trong đối tượng, trong đó sẽ thực hiện phương pháp như getValue(), hoặc là có một cách nào đó tốt hơn việc này? Về cơ bản tất cả những gì tôi cần là biểu diễn chuỗi của mỗi trường được chú thích.

chỉnh sửa: yep field.get(table) hoạt động, nhưng chỉ cho các trường public, có cách nào để thực hiện việc này ngay cả đối với các trường private không? Hoặc tôi có phải làm cho getter và bằng cách nào đó gọi nó?

+0

setAccessible. Phiên bản mảng sẽ nhanh hơn nếu bạn có trình quản lý bảo mật. setAccessible là, tất nhiên, rất nguy hiểm trong các tình huống mà bạn có trình quản lý bảo mật. –

+0

đáng sợ ...có vẻ bạn đang thực hiện phiên bản JPA – basszero

+0

@basszero của riêng bạn: bạn đúng, tôi phải làm điều này cho dự án đại học của tôi vì giáo viên ngu ngốc của tôi sống trong hang và không cho phép sử dụng bất kỳ thư viện nào như Toplink vv ... –

Trả lời

11

Mọi đối tượng phải có toString() được xác định. (Và bạn có thể ghi đè điều này cho mỗi lớp để có được một đại diện có ý nghĩa hơn).

Vì vậy, bạn ở đâu "// ở đây tôi không biết" bình luận là, bạn có thể có của bạn:

Object value = field.get(table); 
// gets the value of this field for the instance 'table' 

log += "value: " + value + "\n"; 
// implicitly uses toString for you 
// or will put 'null' if the object is null 
+0

thx, công trình này, nhưng chỉ khi các trường được khai báo là công khai, khi chúng được riêng tư, tôi nhận được Ngoại lệ trong chuỗi "main" java.lang.IllegalAccessException: Class Main không thể truy cập thành viên của bảng lớp với các công cụ sửa đổi "riêng tư" –

+0

@Darth - hãy xem Field.setAccessible - http://java.sun.com/javase/6/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible (boolean) – McDowell

+0

@McDowell - thx giải quyết vấn đề –

9

Reflection là chính xác cách để giải quyết nó. Tìm hiểu những điều về các loại và các thành viên của chúng tại thời điểm thực hiện là khá nhiều định nghĩa về sự phản chiếu! Cách bạn đã làm nó có vẻ tốt với tôi.

Để tìm giá trị của lĩnh vực này, sử dụng field.get(table)

4

Reflection chính là cách để nhìn vào chú thích. Chúng là một dạng "siêu dữ liệu" gắn liền với lớp hoặc phương thức và chú thích Java được thiết kế để được kiểm tra theo cách đó.

+0

Wow, tôi chia sẻ 5 từ đầu tiên với câu trả lời của Jon, tôi phải cải thiện :) – Uri

+2

Nếu bạn nhìn kỹ, bạn sẽ thấy ông Skeet đã đặt từ thứ ba của mình 'chính xác 'in nghiêng trong khi mục nhập của bạn chỉ ở định dạng không chính xác. Thực hiện tốt cho một bước đi đúng hướng nhưng không có sự nhấn mạnh tinh tế nhưng mang tính mô tả mà Jon đã sử dụng năm từ đầu tiên của bạn vẫn còn thiếu ngắn của ông Skeets. –

2

Phản ánh là một cách để xử lý đối tượng (có lẽ là cách duy nhất nếu các trường là riêng tư và không có bất kỳ loại phương thức truy cập nào). Bạn sẽ cần phải xem Field.setAccessible và có lẽ Field.getType.

Cách tiếp cận khác là tạo một lớp khác để liệt kê các trường được chú thích bằng cách sử dụng compile-time annotation processor. Điều này yêu cầu com.sun API trong Java 5, nhưng hỗ trợ tốt hơn trong Java 6 JDK (IDE như Eclipse có thể yêu cầu cấu hình dự án đặc biệt).

Các vấn đề liên quan