自JDK1.5之后引入注解之后,各個框架中都提供了支持注解的方式。在日常開發中慢慢的將XML許多的配置轉換成注解,經常的使用,各類開源框架中各種注解。在項目中自定義一些注解來方便開發等等。可見注解的易用性和廣泛性。
這邊對注解做一些了解:
元注解:在jdk中提供了 為自定義注解 所需要的幾個元注解:
@interface : 用於定義注解
@Target :用於描述注解的使用范圍 大致有 method(方法) field(屬性) type (類)
@Retention : 注解的生命周期 SOURCE :源文件有效,CLASS :class文件有效, RUNTIME : 運行時有效
@Documented : javadoc記錄標記
然后對應注解類型 自定義 method field type 三類注解:
/** * 自定義注解,目標范圍是字段 * * @author yanbin * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface AnnotationField { public String fieldValue() default "default Field value"; } /** * 自定義注解,目標范圍是方法 * * @author yanbin * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface AnnotationMethod { public String methodValue() default "default Method value"; } /** * 自定義注解,目標是類 * * @author yanbin * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface AnnotationType { public String typeValue() default "default Type value"; }
在一個類上面使用自定義的注解:
/** * 注解使用者 * * @author yanbin * */ @AnnotationType(typeValue = "user Type value") public class AnnotationUser { /** 字段屬性 */ @AnnotationField(fieldValue = "user Field value") private String userField; /** * 使用者方法 */ @AnnotationMethod(methodValue = "user method value") public String userMethod() { return "user default method value"; } /** * 做事 */ public void doIt() { System.out.println(userField); } public String getUserField() { return userField; } public void setUserField(String userField) { this.userField = userField; } }
測試類,解析注解:
/** * 注解測試類,獲取注解關鍵在反射 * * @author yanbin * */ public class AnnotationTest { public static void main(String[] args) { AnnotationTest test = new AnnotationTest(); test.resolve(); test.testDoIt(); } /** * 解析如何獲取注解對應注解中的值 */ @SuppressWarnings({ "rawtypes", "unchecked" }) public void resolve() { try { // 后去對應的類 Class clazz = Class.forName("annotation.user.AnnotationUser"); // 判斷clazz是否存在FirstAnno.class注解 if (clazz.isAnnotationPresent(AnnotationType.class)) { // 存在,則獲取這個注解 AnnotationType annoType = (AnnotationType) clazz.getAnnotation(AnnotationType.class); System.out.println("AnnotationType value: " + annoType.typeValue()); } // 獲取該類的所有方法 Method[] methods = clazz.getDeclaredMethods(); // 解析方法注解 for (Method method : methods) { if (method.isAnnotationPresent(AnnotationMethod.class)) { AnnotationMethod annoMethod = method.getAnnotation(AnnotationMethod.class); System.out.println("AnnotationMethod value: " + annoMethod.methodValue()); } } // 獲取該類的所有屬性字段 Field[] fields = clazz.getDeclaredFields(); // 解析字段注解 for (Field field : fields) { if (field.isAnnotationPresent(AnnotationField.class)) { AnnotationField annoField = field.getAnnotation(AnnotationField.class); System.out.println("AnnotationField value: " + annoField.fieldValue()); } } } catch (SecurityException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 解釋注解中的值,並且賦值給相關屬性或者方法 */ public void testDoIt() { try { AnnotationUser user = new AnnotationUser(); Field field = user.getClass().getDeclaredField("userField"); if (field.isAnnotationPresent(AnnotationField.class)) { AnnotationField annoField = field.getAnnotation(AnnotationField.class); // getDeclaredMethod()返回一個 Method 對象,該對象反映此 Class // 對象所表示的類或接口的指定已聲明方法。name 參數是一個 // String,它指定所需方法的簡稱,parameterTypes 參數是 Class 對象的一個數組 // Method doIt = user.getClass().getDeclaredMethod("doIt"); // 屬性必須要由set 或者get 方法,才能調用invoke方法 PropertyDescriptor pd = new PropertyDescriptor(field.getName(), AnnotationUser.class); Method doIt = pd.getWriteMethod(); if (null != doIt) { String value = annoField.fieldValue(); doIt.invoke(user, value); } } user.doIt(); } catch (Exception e) { e.printStackTrace(); } } }