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

}