@Override:檢查方法是否正確覆蓋父類方法,拼寫錯誤編譯報錯。@Deprecated:標記過時元素,使用時編譯器警告。@SuppressWarnings:抑制特定編譯器警告。| 元註解 | 作用 | 關鍵屬性 |
|---|---|---|
@Target | 限制註解使用位置 | ElementType[] value():METHOD、TYPE、FIELD 等 |
@Retention | 指定註解保留級別 | RetentionPolicy value():SOURCE、CLASS、RUNTIME |
@Documented | 將註解納入 Javadoc | 無 |
@Inherited | 允許子類繼承父類註解 | 無 |
UseCase@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
int id();
String description() default "no description";
}
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 時自動使用默認值。
註解類型必須用 @interface 定義,隱式繼承 java.lang.annotation.Annotation 接口,不可繼承其他類/接口。
// 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 }
@Override)。@Deprecated)。public 或默認訪問權限。value,使用時可省略參數名:@Description("desc")。@Target(ElementType.TYPE) @Retention(RUNTIME) @Documented
public @interface Description { String value(); }
@Target(ElementType.METHOD) @Retention(RUNTIME) @Documented
public @interface Name { String originate(); String community(); }
@Description("javaeye,做最棒的軟件開發交流社區")
public class JavaEyer {
@Name(originate="創始人:robbin", community="javaEye")
public String getName() { return null; }
@Name(originate="創始人:江南白衣", community="springside")
public String getName2() { return "借用兩位的id一用..."; }
}
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());
}
}
}
描述:javaeye,做最棒的軟件開發交流社區 創始人:robbin 創建的社區:javaEye 創始人:江南白衣 創建的社區:springside
註解為代碼注入元數據提供標準化方式,結合反射可實現聲明式編程、自動化代碼生成、框架配置等強大功能。掌握元註解配置、參數規則、處理器編寫,是進階 Java 開發必備技能。