自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(); } } }