简单的注解与反射

目录

1.注解

1.概念与作用

2.java 注解

3.元注解

4.自定义注解

自定义注解

定义数据模型

测试调用

打印日志:

2.反射 

概念和作用

反射类和反射现象

​编辑

 获取方法,属性

 获取注解对象和属性


1.注解

1.概念与作用

从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,

注解的作用:

  • 不是程序本身,可以对程序作出解释

  • 可以在程序编译,类加载,运行时被读取,并执行相应的处理。

2.java 注解

Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。

作用在代码的注解是

  • @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
  • @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
  • @SuppressWarnings - 指示编译器去忽略注解中声明的警告。

作用在其他注解的注解(或者说 元注解)是:

  • @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
  • @Documented - 标记这些注解是否包含在用户文档中。
  • @Target - 标记这个注解应该是哪种 Java 成员。
  • @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

从 Java 7 开始,额外添加了 3 个注解:

  • @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
  • @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
  • @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

3.元注解

元注解是负责对其它注解进行说明的注解,自定义注解时可以使用元注解。Java 5 定义了 4 个注解,分别是 @Documented、@Target、@Retention 和 @Inherited。Java 8 又增加了 @Repeatable 和 @Native 两个注解。这些注解都可以在 java.lang.annotation 包中找到。

4.自定义注解

自定义注解

这里定义两个注解,一个用来赋值,一个用来校验。

/**
 * 性别赋值
 * @author zzs
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
@Inherited
public @interface InitSex {
    /**
     * sex enum
     * @author zzs
     */
    enum SEX_TYPE {MAN, WOMAN}
    SEX_TYPE sex() default SEX_TYPE.MAN;
}

/**
 * 年龄校验
 * @author zzs
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
@Inherited
public @interface ValidateAge {
    /**
     * 最小值
     */
    int min() default 18;
    /**
     * 最大值
     */
    int max() default 99;
    /**
     * 默认值
     */
    int value() default 20;
}

定义数据模型

这里用User类来表示具体待处理的数据对象。

/**
 * user
 *
 * @author zzs
 */
public class User {
    private String username;
    @ValidateAge(min = 20, max = 35, value = 22)
    private int age;
    @InitSex(sex = InitSex.SEX_TYPE.MAN)
    private String sex;
    // 省略getter/setter方法
}

测试调用

具体测试调用的过程,参考代码中的注解,其中initUser方法来演示通过反射给属性赋值,checkUser方法通过反射拿到当前属性的值进行对比校验。

import java.lang.reflect.Field;
/**
 * @author zzs
 */
public class TestInitParam {
    public static void main(String[] args) throws IllegalAccessException {
        User user = new User();
        initUser(user);
        // 年龄为0,校验为通过情况
        boolean checkResult = checkUser(user);
        printResult(checkResult);
        // 重新设置年龄,校验通过情况
        user.setAge(22);
        checkResult = checkUser(user);
        printResult(checkResult);
    }
    static void initUser(User user) throws IllegalAccessException {
        // 获取User类中所有的属性(getFields无法获得private属性)
        Field[] fields = User.class.getDeclaredFields();
        // 遍历所有属性
        for (Field field : fields) {
            // 如果属性上有此注解,则进行赋值操作
            if (field.isAnnotationPresent(InitSex.class)) {
                InitSex init = field.getAnnotation(InitSex.class);
                field.setAccessible(true);
                // 设置属性的性别值
                field.set(user, init.sex().toString());
                System.out.println("完成属性值的修改,修改值为:" + init.sex().toString());
            }
        }
    }
    static boolean checkUser(User user) throws IllegalAccessException {
        // 获取User类中所有的属性(getFields无法获得private属性)
        Field[] fields = User.class.getDeclaredFields();
        boolean result = true;
        // 遍历所有属性
        for (Field field : fields) {
            // 如果属性上有此注解,则进行赋值操作
            if (field.isAnnotationPresent(ValidateAge.class)) {
                ValidateAge validateAge = field.getAnnotation(ValidateAge.class);
                field.setAccessible(true);
                int age = (int) field.get(user);
                if (age < validateAge.min() || age > validateAge.max()) {
                    result = false;
                    System.out.println("年龄值不符合条件");
                }
            }
        }
        return result;
    }
    static void printResult(boolean checkResult) {
        if (checkResult) {
            System.out.println("校验通过");
        } else {
            System.out.println("校验未通过");
        }
    }
}

打印日志:

完成属性值的修改,修改值为:MAN
年龄值不符合条件
校验未通过
校验通过

2.反射 

概念和作用

反射类和反射现象

 获取方法,属性

 获取注解对象和属性

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值