Java Annotations (Chú thích) cho phép chúng ta thêm vào thông tin siêu dữ liệu (metadata information) vào mã nguồn của chúng ta, mặc dù nó không phải là một phần của chương trình. Các Annotation được thêm vào Java kể từ khi JDK 5 được phát hành. Annotation không ảnh hưởng trực tiếp lên các hoạt động của code mà nó chú thích (VD: Nó không ảnh hưởng đến việc thực thi của chương trình).
Hướng dẫn sử dụng Java Annotation và ví dụ minh họa
Trong bài viết hướng dẫn này, chúng ta sẽ lần lượt tìm hiểu qua các chủ đề sau: Việc sử dụng annotations, làm sao để áp dụng annotations, những kiểu annotation được định nghĩa sẵn trong Java và cách để tạo ra các annotation tùy biến.

Các annotation được sử dụng để làm gì?

1) Hướng dẫn cho trình biên dịch: Java được tích hợp sẵn 3 annotation để cung cấp những chỉ dẫn nhất định cho trình biên là: @Deprecated, @Override@SuppressWarnings. Ví dụ: Chú thích @Override được sử dụng để hướng dẫn cho trình biên dịch rằng phương thức được chú thích đang ghi đè phương thức. Chúng ta sẽ tiếp tục thảo luận về những chú thích này trong phần tới.

2) Chỉ dẫn trong lúc biên dịch: (Compile-time) Các chú thích có thể cung cấp hướng dẫn trong lúc biên dịch cho trình biên dịch mà có thể tiếp tục được sử dụng bởi các phần mềm như sinh code, XML file,...

3) Chỉ dẫn trong thời gian chạy: (Runtime) Chúng ta có thể định nghĩa các chú thích và sử dụng trong thời gian chạy mà chúng ta có thể tiếp cận khi sử dụng Java Reflection và có thể sử dụng để đưa ra những hướng dẫn cho chương trình tại Runtime. Chúng ta sẽ thảo luận về vấn đề này khi thực hiện ví dụ trong phần tiếp theo của bài viết nhé.

Cơ bản về Annotations

Một chú thích luôn bắt đầu với ký hiệu @ và sau đó là tên của chú thích. Ký hiệu @ chỉ ra cho trình biên dịch rằng đây là một chú thích.

Ví dụ: @Override
Ký hiệu @ diễn tả đây là một chú thích và Override là tên của chú thích.

Chúng ta có thể sử dụng annotation ở đâu?
Các chú thích có thể áp dụng vào các lớp, giao diện, phương thức và các trường trong chương trình. Ví dụ chú thích bên dưới đây đang được áp dụng cho phương thức.
@Override
void myMethod() { 
    //Do something 
}

Chính xác chú thích này đang làm gì sẽ được giải thích trong phần tiếp tiếp theo, nói một cách tóm tắt thì nó đang hướng dẫn trình biên dịch rằng myMethod() là một phương thức ghi đè của một phương thức cùng tên của lớp cơ sở.

Các chú thích có sẵn trong Java

Java có 3 chú thích được tích hợp sẵn bao gồm:
  • @Override
  • @Deprecated
  • @SuppressWarnings

1) @Override

Khi ghi đè một phương thức trong lớp con (sub-class) chúng ta nên sử dụng chú thích này để đánh dấu phương thức. Điều này giúp cho code dễ đọc và tránh được các vấn đề khi bảo trì, như là: Khi thay đổi tên phương thức ở lớp cơ sở, bạn phải thay đổi luôn cả tên phương thức được ghi đè ở lớp con (nơi mà chú thích này đang được áp dụng) nếu không thì trình biên dịch sẽ ném ra lỗi biên dịch. Như vậy bạn có thể chắc chắn rằng mình không quên thay đổi ở lớp con. Rất khó để tìm dấu vết nếu như bạn không sử dụng chú thích @Override khi ghi đè phương thức.

Ví dụ
public class ParentClass {

    public void doSomething() {
        System.out.println("Parent class method");
    }
}


public class ChildClass extends ParentClass {

    @Override
    public void doSomething() {
        System.out.println("Child class method");
    }
}

2) @Deprecated

Chú thích @Deprecated chỉ ra rằng những phần tử bị đánh dấu (class, method hoặc field) đã không được dùng nữa và không nên tiếp tục dùng nữa. Trình biên dịch sinh ra một cảnh báo bất cứ khi nào chương trình sử dụng một phương thức, lớp hoặc trường đã bị đánh dấu với chú thích @Deprecated. Khi một phần tử bị đánh dấu với chú thích này thì trong Javadoc cũng sẽ bị thêm vào thẻ @deprecated để cảnh báo cho người dùng. Trong ví dụ dưới đây bạn sẽ thấy được nó, lưu ý sự khác nhau giữa @Deprecated and @deprecated nhé, @deprecated được sử dụng cho mục đích tài liệu.
/**
 * @deprecated
 * reason for why it was deprecated
 */
@Deprecated
public void doSomething(){
    // Do something
}
Bây giờ, bất kỳ khi nào chương trình sử dụng phương thức doSomething() trong ví dụ trên, trình biên dịch sẽ sinh ra một cảnh báo cho người dùng.

3) @SuppressWarnings

Chú thích này hướng dẫn cho trình biên dịch bỏ qua những cảnh báo cụ thể. Ví dụ như trong đoạn code dưới đây, tôi đang gọi đến một phương thức đã bị deprecated trước đó và trình biên dịch sẽ sinh ra cảnh báo khi tôi sử dụng phương thức này. Để trình biên dịch bỏ qua cảnh báo của cảnh báo deprecatetion tôi sử dụng @SuppressWarnings("deprecation").
@SuppressWarnings("deprecation")
    void myMethod() {
        myObject.deprecatedMethod();
}

Cách tạo Custom Annotations

  • Các chú thích được tạo bằng cách sử dụng @interface và theo sau đó là tên của chú thích như trong ví dụ bên dưới đây
  • Một chú thích có thể có nhiều phần tử tùy thích và nó trông có vẻ như là một phương thức. Như trong đoạn code dưới đây tôi đã tạo ra 4 phần tử cho chú thích của mình. Mặc dù vậy chúng ta không cung cấp implementation cho các phần tử này nhé.
  • Tất cả các chú thích đều extends từ java.lang.annotation.Annotation interface. Các chú thích không thể bao gồm bất kỳ phép extends nào.
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Documented
@Target(ElementType.TYPE)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation{
    String authorName();
    String creationDate();
    String version() default "";
    String description() default "My custom annotation";
}

Lưu ý rằng: Những phần tử được gán giá trị mặc định khi tạo có thể được bỏ qua khi sử dụng chú thích. Ví dụ, nếu tôi áp dụng chú thích ở trên một class thì nó sẽ như thế này.
@MyCustomAnnotation(
    authorName = "Thuong Nguyen",
   creationDate = "March 23, 2016"
)
public class MyClass {
...
}

... còn tiếp