首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 註解完整指南:從內置註解到自定義註解處理器實戰

     編輯:Java 相關知識

一、註解基礎語法

1. 三大標準註解

  • @Override:檢查方法是否正確覆蓋父類方法,拼寫錯誤編譯報錯。
  • @Deprecated:標記過時元素,使用時編譯器警告。
  • @SuppressWarnings:抑制特定編譯器警告。

2. 四大元註解

元註解作用關鍵屬性
@Target限制註解使用位置ElementType[] value():METHOD、TYPE、FIELD 等
@Retention指定註解保留級別RetentionPolicy value():SOURCE、CLASS、RUNTIME
@Documented將註解納入 Javadoc無
@Inherited允許子類繼承父類註解無

二、自定義註解實戰

1. 定義註解 UseCase

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
    int id();
    String description() default "no description";
}

2. 使用註解

public class PasswordUtils {
    @UseCase(id=47, description="Passwords must contain at least one numeric")
    public boolean validatePassword() { return true; }

    @UseCase(id=48)
    public String encryptPassword(String password) { return password; }

    @UseCase(id=49, description="Jong_Cai")
    public void showName() { System.out.println("Jong_Cai"); }
}

三、編寫註解處理器

利用反射 API getDeclaredMethods()、getAnnotation() 掃描並處理註解。

public class UseCaseTracker {
    public static void trackUseCases(List<Integer> list, Class<?> cl) {
        for (Method m : cl.getDeclaredMethods()) {
            UseCase uc = m.getAnnotation(UseCase.class);
            if (uc != null) {
                System.out.println("Found Use Case:" + uc.id() + " " + uc.description());
                list.remove(new Integer(uc.id()));
            }
        }
        for (int i : list)
            System.out.println("Warning: Missing use case-" + i);
    }

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        Collections.addAll(list, 47,48,49,50,51);
        trackUseCases(list, PasswordUtils.class);
    }
}

輸出:找到 47、48、49;報警缺失 50、51。未指定 description 時自動使用默認值。

四、深度剖析:註解設計原理

1. @interface 關鍵字

註解類型必須用 @interface 定義,隱式繼承 java.lang.annotation.Annotation 接口,不可繼承其他類/接口。

2. 元註解源碼解讀

// Target.java
@Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE)
public @interface Target { ElementType[] value(); }

// Retention.java
@Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE)
public @interface Retention { RetentionPolicy value(); }

// RetentionPolicy.java
public enum RetentionPolicy { SOURCE, CLASS, RUNTIME }

// ElementType.java
public enum ElementType { TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE }

3. 保留策略詳解

  • SOURCE:僅源碼保留,編譯後丟棄(如 @Override)。
  • CLASS:編譯進 class 文件,運行時不加載 JVM(默認)。
  • RUNTIME:運行時加載 JVM,可通過反射讀取(如 @Deprecated)。

4. 參數成員規則

  • 只能用 public 或默認訪問權限。
  • 類型限於:8 基本類型、String、Enum、Class、Annotation、及其數組。
  • 單參數建議命名為 value,使用時可省略參數名:@Description("desc")。

五、完整自定義註解示例

1. 註解定義

@Target(ElementType.TYPE) @Retention(RUNTIME) @Documented
public @interface Description { String value(); }

@Target(ElementType.METHOD) @Retention(RUNTIME) @Documented
public @interface Name { String originate(); String community(); }

2. 使用註解

@Description("javaeye,做最棒的軟件開發交流社區")
public class JavaEyer {
    @Name(originate="創始人:robbin", community="javaEye")
    public String getName() { return null; }

    @Name(originate="創始人:江南白衣", community="springside")
    public String getName2() { return "借用兩位的id一用..."; }
}

3. 反射解析

public class TestAnnotation {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("lighter.javaeye.com.JavaEyer");
        // 類級註解
        if (clazz.isAnnotationPresent(Description.class)) {
            Description des = clazz.getAnnotation(Description.class);
            System.out.println("描述:" + des.value());
        }
        // 方法級註解
        Set<Method> set = new HashSet<>();
        for (Method m : clazz.getMethods())
            if (m.isAnnotationPresent(Name.class)) set.add(m);
        for (Method m : set) {
            Name n = m.getAnnotation(Name.class);
            System.out.println(n.originate());
            System.out.println("創建的社區:" + n.community());
        }
    }
}

4. 運行輸出

描述:javaeye,做最棒的軟件開發交流社區
創始人:robbin
創建的社區:javaEye
創始人:江南白衣
創建的社區:springside

六、總結

註解為代碼注入元數據提供標準化方式,結合反射可實現聲明式編程、自動化代碼生成、框架配置等強大功能。掌握元註解配置、參數規則、處理器編寫,是進階 Java 開發必備技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved