Lấy giá trị của annotation và giá trị của field trong java

// tự định nghĩa 1 annotation
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@interface Max {
    double value() default 10000;
}
public class Student {
    private String fullname=null;
    @Max(value = 123)
    private int ID=0;
}
public static void main(String[] args) throws NoSuchFieldException {
        Field field = Student.class.getDeclaredField("ID");
        Max annotations = field.getAnnotation(Max.class);
        System.out.println(annotations.value()); // output: 123
}

Chào các a/c. Em đang làm 1 cái Validator. Hiện tại ý tưởng của e là tự build các annotation như min,max, notnull, … sau đó sẽ lấy giá trị của annotation và so sánh nó với giá trị của field (vd: ID như trong ví dụ) hiện tại.

Em tìm ra được cách lấy ra giá trị của annotation nhưng giờ e muốn viết 1 hàm tổng quát kiểu:

void validate(Class studentType, Object studentObj, String field )
{
   // Lấy ra giá trị của field trong studentObj
  // Lấy ra giá trị của tất cả annotation của field trong class studentType
  // Tùy thuộc vào loại annotation mà gọi hàm checkValid để kiểm tra (giá trị của annotation và giá trị của field, nếu invalid thì thông báo)
}

Mn có thể gợi ý cho e cách làm k ạ! E cảm ơn!

Hi there,

Thực ra cậu đang chế lại 1 cái bánh xe rất to đấy :smile:
Việc dùng annotation để đánh dấu cách validate đã được định nghĩa trong Bean validation, và có 1 implementation cậu có thể dùng của Hibernate (trong link này là hướng dẫn dùng Bean validation 2.0 luôn).
Cậu có thể dùng nó luôn mà không cần phải tự cài đặt lại.

Tuy nhiên, nếu cậu vẫn muốn cài đặt lại, cậu có thể sử dụng AOP:

  • Cậu cần định nghĩa chiến lược validate cho từng annotation. Trong đó sẽ lấy giá trị mà cậu cần validate trong object, rồi so sánh nó với giá trị lấy được từ annotation.
  • Ở hàm validate tổng quát, cậu gọi tới code chứa chiến lược validate ở trên. Phần này, để cho tổng quát, cậu cần dùng reflection (cậu đã dùng nó rồi), duyệt hết tất cả các field, lấy ra trường có xuất hiện annotation, rồi gọi tới chiến lược validate tương ứng với annotation kia.
    Nếu cậu có validate cả method/class, cậu cũng làm tương tự như trên, chỉ sửa cách dùng reflection thôi.
  • Định nghĩa pointcut, nơi trigger method validate tổng quát của cậu

Đó cũng là cách Hibernate implement Bean validation 2.0 spec luôn. Cậu thực sự nên tham khảo cách họ implement Bean validation 3.0 (cách làm tương tự như Bean validation 2.0 thôi cậu). Nếu cậu vẫn muốn cài đặt, đấy là role model thành công nhất dành cho cậu :smile:

Hope it helps!

6 Likes

Thanks anh! vì đây là đồ án viết validator nên e mới phải viết lại :smile:
E đang viết thử như vầy nhưng nó báo lỗi: java.lang.IllegalArgumentException: object is not an instance of declaring class.

public class AnnotationReader {
    public static Object getValue(Class<?> classType, Class annotationType, String fieldName) throws NoSuchFieldException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Field field = classType.getDeclaredField(fieldName);
        Annotation annotation = field.getAnnotation(annotationType);
        //System.out.println(annotation.annotationType());
        //Max a=(Max)annotation;
        int val= (int)annotation.annotationType().getMethods()[0].invoke(classType.newInstance());
        System.out.println(val);
        return null;
    }
}
//MAIN
Student student = new Student();
student.setID(10);
System.out.println(student.getID());
AnnotationReader.getValue(Student.class, Max.class, "ID");

ở dòng comment ép kiểu về annotation Max thì gọi a.value() sẽ lấy được giá trị của Max trong Student. nhưng e muốn truyền vào tham số kiểu Class thôi nên chưa biết là thế nào để invoke được method value() của Max , mặc dù e đã truyền tham số là 1 instance classType.newInstance()

Vây nên viết rule-engine



Hoặc viết cái DBC(Design by contract)

@Requires("book != null")
@Ensures("books.count(book) == old(books.count(book)) + copies")
public void addBooks(Book book, int copies) {
    books.add(book, copies);
}

2 cai này cai nào cũng có thể làm đồ án được.

Tham khảo cái FieldUtils của lang.common

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?