注解与反射的简单使用

1.全部代码

1.user

public class User {

    @ViewInject(age = 22,name="sunweihao")//为注解设置值
    private String name;
    private int age;

    private String watch(String TV){
        return "看"+TV;
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

2.ViewInject

public class AnnotationMainTest {
    public static void main(String[] args) throws Exception {
        /**
         * 需求:获取User类中name字段上的自定义注解的值,然后将该值通过反射设置给User对象中的属性
         */
        User user=new User();
        /**
         * 获取到User类的字节码
         */
        Class<User> userClass = User.class;
        /**
         * 将字节码的name、age字段获取到
         */
        Field userClassDeclaredField = userClass.getDeclaredField("name");//获取到user类的对象
        Field userClassDeclaredFieldAge = userClass.getDeclaredField("age");
        /**
         * 将当前字段的注解对象获取到
         */
        ViewInject viewInject = userClassDeclaredField.getAnnotation(ViewInject.class);//userClassDeclaredField要注解位置的那个
        if (viewInject!=null) {
            /**
             * 获取自定义对象的参数
             */
            int age = viewInject.age();
            String name = viewInject.name();
            System.out.println(name+age);
            /**
             * 通过暴力反射,将这两个值设置给对象,因为他们是私有的
             */
            userClassDeclaredField.setAccessible(true);//设置允许访问,其实就是暴力反射
            userClassDeclaredField.set(user,name);//给user对象的declaredField 设置值为name

            userClassDeclaredFieldAge.setAccessible(true);//设置允许访问,其实就是暴力反射
            userClassDeclaredFieldAge.set(user,age);//给user对象的declaredField 设置值为name
            System.out.println(user.toString());
        }else {
            System.out.println("为空");
        }
        //根据方法名进行方法反射
        Method declaredMethod = userClass.getDeclaredMethod("watch", String.class);
        declaredMethod.setAccessible(true);//一定
        Object invoke = declaredMethod.invoke(user, "苍井空电影");
        System.out.println(invoke);
    }
}
@Target(ElementType.FIELD)//作用领域
//@Retention(RetentionPolicy.SOURCE)//源码编译成字节码时,会把User类里的@ViewInject(即注解信息)清除掉
//@Retention(RetentionPolicy.CLASS)//该注解会被编译到字节码中,但是当虚拟机全加载这个字节码的时候,注解信息就被清除
@Retention(RetentionPolicy.RUNTIME)//该注解类一直保留到加载到虚拟机中
public @interface ViewInject {
    //两个参数
    int age();
    String name();
}

3.AnnotationMainTest

2.步骤

1.写注解类

设置作用域在参数上,注解的持续时间一直保留到虚拟机中

@Target(ElementType.FIELD)//作用领域
//@Retention(RetentionPolicy.SOURCE)//源码编译成字节码时,会把User类里的@ViewInject(即注解信息)清除掉
//@Retention(RetentionPolicy.CLASS)//该注解会被编译到字节码中,但是当虚拟机全加载这个字节码的时候,注解信息就被清除
@Retention(RetentionPolicy.RUNTIME)//该注解类一直保留到加载到虚拟机中
public @interface ViewInject {
    //两个参数
    int age();
    String name();
}

2.写User类并添加注解

这里注解位置在name上,这个类似标识,用于获取注解类

public class User {

    @ViewInject(age = 22,name="sunweihao")//为注解设置值
    private String name;
    private int age;

    private String watch(String TV){
        return "看"+TV;
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

3.获取user类中的字段:name

User user=new User();
        /**
         * 1.获取到User类的字节码
         */
        Class<User> userClass = User.class;
        /**
         * 将字节码的name字段获取到
         */
        Field userClassDeclaredField = userClass.getDeclaredField("name");//name的字段

4.根据user类字段的标识,来获取注解类ViewInject.class

ViewInject viewInject = userClassDeclaredField.getAnnotation(ViewInject.class);

5.获取注解类的值,并为user设置值

int age = viewInject.age();
            String name = viewInject.name();
            System.out.println(name+age);
            /**
             * 通过暴力反射,将这两个值设置给对象,因为他们是私有的
             */
            userClassDeclaredField.setAccessible(true);//设置允许访问,其实就是暴力反射
            userClassDeclaredField.set(user,name);//类,为name字段设置值

6.图解:

在这里插入图片描述

1.方法反射

//根据方法名进行方法反射
        Method declaredMethod = userClass.getDeclaredMethod("watch", String.class);
        declaredMethod.setAccessible(true);//一定
        Object invoke = declaredMethod.invoke(user, "苍井空电影");
        System.out.println(invoke);

3.问题与反思

1.反射的意义:

为达需求,打破封装思想,面向对象,有些时候我们要拿封装里面的东西,但是拿不到,我们就可以通过反射的形式来打破封装

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值