• Java自定义注解


    Java在1.5开始引入了注解,目前流行的框架都在用注解,可想而知注解的强大之处。

    以下通过自定义注解来深入了解java注解。

    一、创建自定义注解

    package com.sam.annotation;
    import java.lang.annotation.*;
    
    /**
     * @author sam
     * @since 2017/7/13
     */
    @Target({ElementType.METHOD, ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface MyMessage {
    
        String name() default "sam";
    
        int num() default 0;
    
        String desc();
    
    }
    
    

    说明:

    @Target、@Retention、@Inherited、@Documented为元注解(meta-annotation),它们是负责注解其他注解的。
    1. Target:指明注解支持的使用范围,取值可以参考枚举ElementType,以下:
      • ElementType.TYPE //类、接口、枚举
      • ElementType.FIELD //属性
      • ElementType.METHOD //方法
      • ElementType.PARAMETER //参数
      • ElementType.CONSTRUCTOR //构造器
      • ElementType.LOCAL_VARIABLE //局部变量
      • ElementType.ANNOTATION_TYPE //注解
      • ElementType.PACKAGE //包
    2. Retention:指明注解保留的的时间长短,取值参考枚举RetentionPolicy,一下:
      • SOURCE //源文件中保留
      • CLASS //class编译时保留
      • RUNTIME //运行时保留
    3. Inherited:指明该注解类型被自动继承。如果一个annotation注解被@Inherited修饰,那么该注解作用于的类 的子类也会使用该annotation注解。
    4. Documented:指明拥有这个注解的元素可以被javadoc此类的工具文档化。

    二、创建测试类,使用自定义注解

    package com.sam.annotation;
    /**
     * @author sam
     * @since 2017/7/13
     */
    public class AnnotationTest {
    
        @MyMessage(num = 10, desc = "参数a")
        private static int a;
    
    
        @MyMessage(name = "Sam test", desc = "测试方法test")
        public void test() {
            System.out.println("test");
        }
    
    }
    
    
    在该类中的属性和方法,使用了自定义的注解,并指明了参数。
    那么现在就需要解析自定义的注解。

    三、解析注解

    使用反射机制处理自定义注解
    package com.sam.annotation;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * 使用反射处理注解
     *
     * @author sam
     * @since 2017/7/13
     */
    public class MyMessageProcessor {
    
        public static void main(String[] args) {
    
            try {
    
                //加载annotationTest.class类
                Class clazz = MyMessageProcessor.class.getClassLoader().loadClass("com.sam.annotation.AnnotationTest");
    
                //获取属性
                Field[] fields = clazz.getDeclaredFields();
                //遍历属性
                for (Field field : fields) {
                    MyMessage myMessage = field.getAnnotation(MyMessage.class);
                    System.out.println("name:" + myMessage.name() + "  num:" + myMessage.num() + "  desc:" + myMessage.desc());
                }
    
                //获取类中的方法
                Method[] methods = clazz.getMethods();
                //遍历方法
                for (Method method : methods) {
    
                    //判断方法是否带有MyMessage注解
                    if (method.isAnnotationPresent(MyMessage.class)) {
                        // 获取所有注解 method.getDeclaredAnnotations();
                        // 获取MyMessage注解
                        MyMessage myMessage = method.getAnnotation(MyMessage.class);
                        System.out.println("name:" + myMessage.name() + "  num:" + myMessage.num() + "  desc:" + myMessage.desc());
                    }
                }
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    
    }
    
    
    运行MyMessageProcessor 得到结果:
    name:sam  num:10  desc:参数a
    name:Sam test  num:0  desc:测试方法test
    
    Process finished with exit code 0
    
    具体定制注解所实现的内容,可以在MyMessageProcessor.java中进行修改。
    自此,已经对java的自定义注解有简单的了解。
  • 相关阅读:
    PrintWriter write与println方法的区别
    java线程之一 单线程
    Android系列之ListView实现分页和类似异步加载效果(转载)
    Failed to fetch URL http://dlssl.google.com/android/repository/addons_list
    java rpc 综述(上)
    横竖屏切换时候Activity的生命周期
    【转载】C# 大数相乘
    ASP.NET 2.0 中使用PreviousPage的强类型属性
    人生一世
    SQL 中的indexof函数CHARINDEX
  • 原文地址:https://www.cnblogs.com/magicalSam/p/7160926.html
Copyright © 2020-2023  润新知