java注解
自 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 {</span><span style="color: rgba(0, 0, 255, 1)">public</span> String fieldValue() <span style="color: rgba(0, 0, 255, 1)">default</span> "default Field value"<span style="color: rgba(0, 0, 0, 1)">;
}
/**
- 自定义注解,目标范围是方法
- @author yanbin
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AnnotationMethod {</span><span style="color: rgba(0, 0, 255, 1)">public</span> String methodValue() <span style="color: rgba(0, 0, 255, 1)">default</span> "default Method value"<span style="color: rgba(0, 0, 0, 1)">;
}
/**
- 自定义注解,目标是类
- @author yanbin
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AnnotationType {</span><span style="color: rgba(0, 0, 255, 1)">public</span> String typeValue() <span style="color: rgba(0, 0, 255, 1)">default</span> "default Type value"<span style="color: rgba(0, 0, 0, 1)">;
}
在一个类上面使用自定义的注解:
/** * 注解使用者 * * @author yanbin * */ @AnnotationType(typeValue = "user Type value") public class AnnotationUser {</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> 字段属性 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)"> @AnnotationField(fieldValue </span>= "user Field value"<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String userField; </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> * 使用者方法 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)"> @AnnotationMethod(methodValue </span>= "user method value"<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String userMethod() { </span><span style="color: rgba(0, 0, 255, 1)">return</span> "user default method value"<span style="color: rgba(0, 0, 0, 1)">; } </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> * 做事 </span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> doIt() { System.out.println(userField); } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getUserField() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> userField; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setUserField(String userField) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.userField =<span style="color: rgba(0, 0, 0, 1)"> userField; }
}
测试类,解析注解:
/** * 注解测试类,获取注解关键在反射 * * @author yanbin * */ public class AnnotationTest {</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> main(String[] args) { AnnotationTest test </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AnnotationTest(); test.resolve(); test.testDoIt(); } </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> * 解析如何获取注解对应注解中的值 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)"> @SuppressWarnings({ </span>"rawtypes", "unchecked"<span style="color: rgba(0, 0, 0, 1)"> }) </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> resolve() { </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 后去对应的类</span> Class clazz = Class.forName("annotation.user.AnnotationUser"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 判断clazz是否存在FirstAnno.class注解</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (clazz.isAnnotationPresent(AnnotationType.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">)) { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 存在,则获取这个注解</span> AnnotationType annoType = (AnnotationType) clazz.getAnnotation(AnnotationType.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); System.out.println(</span>"AnnotationType value: " +<span style="color: rgba(0, 0, 0, 1)"> annoType.typeValue()); } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取该类的所有方法</span> Method[] methods =<span style="color: rgba(0, 0, 0, 1)"> clazz.getDeclaredMethods(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 解析方法注解</span> <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (Method method : methods) { </span><span style="color: rgba(0, 0, 255, 1)">if</span> (method.isAnnotationPresent(AnnotationMethod.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">)) { AnnotationMethod annoMethod </span>= method.getAnnotation(AnnotationMethod.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); System.out.println(</span>"AnnotationMethod value: " +<span style="color: rgba(0, 0, 0, 1)"> annoMethod.methodValue()); } } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取该类的所有属性字段</span> Field[] fields =<span style="color: rgba(0, 0, 0, 1)"> clazz.getDeclaredFields(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 解析字段注解</span> <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (Field field : fields) { </span><span style="color: rgba(0, 0, 255, 1)">if</span> (field.isAnnotationPresent(AnnotationField.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">)) { AnnotationField annoField </span>= field.getAnnotation(AnnotationField.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); System.out.println(</span>"AnnotationField value: " +<span style="color: rgba(0, 0, 0, 1)"> annoField.fieldValue()); } } } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (SecurityException e) { e.printStackTrace(); } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (ClassNotFoundException e) { e.printStackTrace(); } } </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> * 解释注解中的值,并且赋值给相关属性或者方法 </span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> testDoIt() { </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { AnnotationUser user </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AnnotationUser(); Field field </span>= user.getClass().getDeclaredField("userField"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (field.isAnnotationPresent(AnnotationField.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">)) { AnnotationField annoField </span>= field.getAnnotation(AnnotationField.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> getDeclaredMethod()返回一个 Method 对象,该对象反映此 Class </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 对象所表示的类或接口的指定已声明方法。name 参数是一个 </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String,它指定所需方法的简称,parameterTypes 参数是 Class 对象的一个数组 </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Method doIt = user.getClass().getDeclaredMethod("doIt"); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 属性必须要由set 或者get 方法,才能调用invoke方法</span> PropertyDescriptor pd = <span style="color: rgba(0, 0, 255, 1)">new</span> PropertyDescriptor(field.getName(), AnnotationUser.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); Method doIt </span>=<span style="color: rgba(0, 0, 0, 1)"> pd.getWriteMethod(); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">null</span> !=<span style="color: rgba(0, 0, 0, 1)"> doIt) { String value </span>=<span style="color: rgba(0, 0, 0, 1)"> annoField.fieldValue(); doIt.invoke(user, value); } } user.doIt(); } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) { e.printStackTrace(); } }
}