• Java自定义注解


    Java自定义注解

     

    前言:这两天看了一下Java自定义注解的内容,然后按照我自己的理解写了两份代码,还挺有趣的,本文包括三个部分:注解的基础、通过注解进行赋值(结合了工厂方法模式)、通过注解进行校验。

     

    一、注解的基础

    1.注解的定义:Java文件叫做Annotation,用@interface表示。

    2.元注解:@interface上面按需要注解上一些东西,包括@Retention、@Target、@Document、@Inherited四种。

    3.注解的保留策略:

      @Retention(RetentionPolicy.SOURCE)   // 注解仅存在于源码中,在class字节码文件中不包含

      @Retention(RetentionPolicy.CLASS)     // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得

      @Retention(RetentionPolicy.RUNTIME)  // 注解会在class字节码文件中存在,在运行时可以通过反射获取到

    4.注解的作用目标:

      @Target(ElementType.TYPE)                      // 接口、类、枚举、注解

      @Target(ElementType.FIELD)                     // 字段、枚举的常量

      @Target(ElementType.METHOD)                 // 方法

      @Target(ElementType.PARAMETER)            // 方法参数

      @Target(ElementType.CONSTRUCTOR)       // 构造函数

      @Target(ElementType.LOCAL_VARIABLE)   // 局部变量

      @Target(ElementType.ANNOTATION_TYPE) // 注解

      @Target(ElementType.PACKAGE)               //

    5.注解包含在javadoc中:

      @Documented

    6.注解可以被继承:

      @Inherited

    7.注解解析器:用来解析自定义注解。

    二、通过注解进行赋值(结合了工厂方法模式)

      1.自定义注解

    package annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Documented
    @Inherited
    @Target({ ElementType.FIELD, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Init
    {
        public String value() default "";
    }

      2.在数据模型使用注解

    package model;
    
    import annotation.Init;
    
    public class User
    {
        private String name;
        private String age;
    
        public String getName()
        {
            return name;
        }
    
        @Init(value = "liang")
        public void setName(String name)
        {
            this.name = name;
        }
    
        public String getAge()
        {
            return age;
        }
    
        @Init(value = "23")
        public void setAge(String age)
        {
            this.age = age;
        }
    }

      3.用“构造工厂”充当“注解解析器”

    package factory;
    
    import java.lang.reflect.Method;
    
    import annotation.Init;
    import model.User;
    
    public class UserFactory
    {
        public static User create()
        {
            User user = new User();
    
            // 获取User类中所有的方法(getDeclaredMethods也行)
            Method[] methods = User.class.getMethods();
    
            try
            {
                for (Method method : methods)
                {
                    // 如果此方法有注解,就把注解里面的数据赋值到user对象
                    if (method.isAnnotationPresent(Init.class))
                    {
                        Init init = method.getAnnotation(Init.class);
                        method.invoke(user, init.value());
                    }
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
                return null;
            }
    
            return user;
        }
    }

      4.运行的代码

    package app;
    
    import java.lang.reflect.InvocationTargetException;
    
    import factory.UserFactory;
    import model.User;
    
    public class Test
    {
        public static void main(String[] args) throws IllegalAccessException,
                IllegalArgumentException, InvocationTargetException
        {
            User user = UserFactory.create();
    
            System.out.println(user.getName());
            System.out.println(user.getAge());
        }
    }

      5.运行结果

    liang
    23

    三、通过注解进行校验

      1.自定义注解

    package annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Documented
    @Inherited
    @Target({ ElementType.FIELD, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Validate
    {
        public int min() default 1;
    
        public int max() default 10;
    
        public boolean isNotNull() default true;
    }

      2.在数据模型使用注解

    package model;
    
    import annotation.Validate;
    
    public class User
    {
        @Validate(min = 2, max = 5)
        private String name;
    
        @Validate(isNotNull = false)
        private String age;
    
        public String getName()
        {
            return name;
        }
    
        public void setName(String name)
        {
            this.name = name;
        }
    
        public String getAge()
        {
            return age;
        }
    
        public void setAge(String age)
        {
            this.age = age;
        }
    }

      3.注解解析器

    package check;
    
    import java.lang.reflect.Field;
    
    import annotation.Validate;
    import model.User;
    
    public class UserCheck
    {
        public static boolean check(User user)
        {
            if (user == null)
            {
                System.out.println("!!校验对象为空!!");
                return false;
            }
    
            // 获取User类的所有属性(如果使用getFields,就无法获取到private的属性)
            Field[] fields = User.class.getDeclaredFields();
    
            for (Field field : fields)
            {
                // 如果属性有注解,就进行校验
                if (field.isAnnotationPresent(Validate.class))
                {
                    Validate validate = field.getAnnotation(Validate.class);
                    if (field.getName().equals("age"))
                    {
                        if (user.getAge() == null)
                        {
                            if (validate.isNotNull())
                            {
                                System.out.println("!!年龄可空校验不通过:不可为空!!");
                                return false;
                            }
                            else
                            {
                                System.out.println("年龄可空校验通过:可以为空");
                                continue;
                            }
                        }
                        else
                        {
                            System.out.println("年龄可空校验通过");
                        }
    
                        if (user.getAge().length() < validate.min())
                        {
                            System.out.println("!!年龄最小长度校验不通过!!");
                            return false;
                        }
                        else
                        {
                            System.out.println("年龄最小长度校验通过");
                        }
    
                        if (user.getAge().length() > validate.max())
                        {
                            System.out.println("!!年龄最大长度校验不通过!!");
                            return false;
                        }
                        else
                        {
                            System.out.println("年龄最大长度校验通过");
                        }
                    }
                    if (field.getName().equals("name"))
                    {
                        if (user.getName() == null)
                        {
                            if (validate.isNotNull())
                            {
                                System.out.println("!!名字可空校验不通过:不可为空!!");
                                return false;
                            }
                            else
                            {
                                System.out.println("名字可空校验通过:可以为空");
                                continue;
                            }
                        }
                        else
                        {
                            System.out.println("名字可空校验通过");
                        }
    
                        if (user.getName().length() < validate.min())
                        {
                            System.out.println("!!名字最小长度校验不通过!!");
                            return false;
                        }
                        else
                        {
                            System.out.println("名字最小长度校验通过");
                        }
    
                        if (user.getName().length() > validate.max())
                        {
                            System.out.println("!!名字最大长度校验不通过!!");
                            return false;
                        }
                        else
                        {
                            System.out.println("名字最大长度校验通过");
                        }
                    }
                }
            }
    
            return true;
        }
    }

      4.运行的代码

    package app;
    
    import check.UserCheck;
    import model.User;
    
    public class Test
    {
        public static void main(String[] args)
        {
            User user = new User();
            
            user.setName("liang");
            user.setAge("1");
            
            System.out.println(UserCheck.check(user));
        }
    }

      5.运行结果

    名字可空校验通过
    名字最小长度校验通过
    名字最大长度校验通过
    年龄可空校验通过
    年龄最小长度校验通过
    年龄最大长度校验通过
    true

     

  • 相关阅读:
    ora29861:域索引标记为loading/failed/unusable(转载)
    总遇到些莫名奇妙的问题,很不爽!
    dul 10恢复oracle lob数据方法(转载)
    C#用GDAL/OGR库创建与写Shape文件(转载)
    缺陷跟踪系统Mantis之安装篇(转载)
    Oracle10g闪回恢复区详细解析(转载)
    五大最受欢迎的BUG管理系统(转载)
    使用dul恢复数据(转载)
    DUL使用(转载)
    gdul 1.0.2 使用
  • 原文地址:https://www.cnblogs.com/liangweiping/p/3837332.html
Copyright © 2020-2023  润新知