反射的用法及其介绍

反射的用法及其介绍

反射的好处

有两个方向

​ 第一个方向:无视修饰符访问类中的内容。但是这种操作在开发中一般不用,都是框架层来用的。

​ 第二个方向:反射可以跟配置文件结合起来使用,动态的创建对象,动态的调用方法。

获取字节码文件对象的三种方式

  • Class这个类里面的静态方法forName(“全类名”)(最常用)

    Class clazz1=Class.forName("类的全类名");
    
  • 通过class属性获取

    //类名.class
    Class clazz2 = Student.class;
    
  • 通过对象获取字节码文件对象

    Student s = new Student();
    Class clazz3 = s.getClass();
    

获取构造方法

规则:

​ get表示获取,Declared表示私有,最后的s表示所有,复数形式.

​ 如果当前获取到的是私有的,必须要临时修改访问权限,否则无法使用

方法名说明
Constructor<?>[] getConstructors()获得所有的构造(只能public修饰)
Constructor<?>[] getDeclaredConstructors()获得所有的构造(包含private修饰)
Constructor getConstructor(Class<?>… parameterTypes)获取指定构造(只能public修饰)
Constructor getDeclaredConstructor(Class<?>… parameterTypes)获取指定构造(包含private修饰)

获得所有构造用Constructor[]接受,for循环遍历

获取指定构造参数格式要以下形式:

Constructor con = clazz.getDeclaredConstructor(String.class, int.class);

获取的构造方法就是这类:
在这里插入图片描述

获取构造方法的权限修饰符和每个参数

//获取构造方法的权限修饰符
int modifiers = con.getModifiers();
//获取构造方法的每个参数
Parameter[] parameters = con.getParameters();

实例化对象

涉及到的方法:newInstance

如果将私有构造方法创建对象,需要临时修改构造方法的访问权限(暴力反射)

//1.获取整体的字节码文件对象
Class clazz = Class.forName("全类名");
//2.获取有参构造方法
Constructor con1 = clazz.getDeclaredConstructor(String.class);
 Constructor con2 = clazz.getDeclaredConstructor(String.class, int.class);

//3.利用构造方法创建对象
student stu =(student) con1.newInstance("funnyboy");
System.out.println(stu);
//3.将私有构造方法创建对象
//临时取消权限校验
con2.setAccessible(true);
student stu2 = (student) con2.newInstance("kai桑", 20);
System.out.println(stu2);

获取成员变量

方法名说明
Field[] getFields()返回所有成员变量对象的数组(只能拿public的)
Field[] getDeclaredFields()返回所有成员变量对象的数组,存在就能拿到
Field getField(String name)返回单个成员变量对象(只能拿public的)
Field getDeclaredField(String name)返回单个成员变量对象,存在就能拿到

1.获取class对象

2.获取成员变量的对象(Field对象)

 Field[] fields2 = clazz.getDeclaredFields("name");

获取成员变量并获取值和修改值

方法说明
void set(Object obj, Object value)赋值
Object get(Object obj)获取值
		//1.获取class对象
        Class clazz = Class.forName("reflect.student");
        //2.获取指定的成员变量
        Field name=clazz.getDeclaredField("name");
        System.out.println(name);

        //3.获取成员变量记录的值
        student s = new student("zhangsan", 23);
		//产生Student对象		
        Object obj =clazz.getDeclaredConstructor().newInstance();
        //临时取消权限校验
        name.setAccessible(true);
		//Field成员变量的get返回的是object需要强转
        String value =(String)name.get(s);
        System.out.println(value);

        //修改对象里面记录的值
        name.set(s,"lisi");
        name.set(obj,"zxk");
        System.out.println(s);
        System.out.println(obj);//private java.lang.String reflect.student.name
//zhangsan
//student{name='lisi', age=23}
//student{name='zxk', age=0}

获取成员变量的权限修饰符,名字,数据类型

		//1.获取class对象
        Class clazz = Class.forName("reflect.student");
        //2.获取单个的成员变量
        Field name=clazz.getDeclaredField("name");
        System.out.println(name);

        //获取权限修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);
        //获取成员变量的名字
        String n = name.getName();
        System.out.println(n);
        //获取成员变量的数据类型
        Class<?> type = name.getType();
        System.out.println(type);

获取成员方法

方法名说明
Method[] getMethods()返回所有成员方法对象的数组(只能拿public的)
Method[] getDeclaredMethods()返回所有成员方法对象的数组,存在就能拿到
Method getMethod(String name, Class<?>… parameterTypes)返回单个成员方法对象(只能拿public的)
Method getDeclaredMethod(String name, Class<?>… parameterTypes)返回单个成员方法对象,存在就能拿到

1.获取class对象

2.获取获取方法(包含私有)

 Method[] methods2 = clazz.getDeclaredMethods();

2.或者获取指定方法

Method method4 = clazz.getMethod("eat",String.class);
//写参数防止方法的重载

获取成员方法并运行

Object invoke(Object obj, Object… args) :运行方法

参数一:用obj对象调用该方法

参数二:调用方法的传递的参数(如果没有就不写)

返回值:方法的返回值(如果没有就不写)

 		//1.获取字节码文件对象
        Class clazz = Class.forName("com.itheima.a02reflectdemo1.Student");
		
        //2.获取一个对象
        //需要用这个对象去调用方法
        //获取一个对象
        Object obj = clazz.getDeclaredConstructor().newInstance();
        
        //3.获取一个指定的方法
        //参数一:方法名
        //参数二:参数列表,如果没有可以不写
        Method eatMethod = clazz.getMethod("eat",String.class);
        
        //运行
        //参数一:表示方法的调用对象
        //参数二:方法在运行时需要的实际参数
        //注意点:如果方法有返回值,那么需要接收invoke的结果
        //如果方法没有返回值,则不需要接收
        String result = (String) eatMethod.invoke(obj, "重庆小面");
		//运行此方法后,并返回值
        System.out.println(result);
        //参数二:方法在运行时需要的实际参数
        //注意点:如果方法有返回值,那么需要接收invoke的结果
        //如果方法没有返回值,则不需要接收
        String result = (String) eatMethod.invoke(obj, "重庆小面");
		//运行此方法后,并返回值
        System.out.println(result);
  • 25
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值