Java反射

反射

官方解释:Reflection允许以编程的方式访问有关已加载类的字段、方法和构造函数的信息,以及使用反射字段、方法和构造函数在封装和安全限制内对其底层对应项进行操作(其实指的是加载类的字节码到内存,并以编程的方法解刨出类中的各个成分(成员变量、方法、构造器等)

在这里插入图片描述

因为反射获取的是类的信息,那么反射的第一步首先获取到类才行。由于Java的设计原则是万物皆对象,获取到的类其实也是以对象的形式体现的,叫字节码对象,用Class类来表示。获取到字节码对象之后,再通过字节码对象就可以获取到类的组成成分了,这些组成成分其实也是对象,其中每一个成员变量用Field类的对象来表示每一个成员方法用Method类的对象来表示每一个构造器用Constructor类的对象来表示

1.1获取类的字节码对象

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

     //1.通过类
     Class c1 = Student.class;  
     //2.通过全类名
     Class c2 = Class.forName("com.itheima.d2_reflect.Student");
     System.out.println(c1 == c2); //true
     //3.通过对象
     Student s = new Student();
     Class c3 = s.getClass();
    

1.2 获取类的构造器&使用

  • Class类中获取构造器的方法

在这里插入图片描述

  • 代码演示

     //1、反射第一步:必须先得到这个类的Class对象
     Class c = Cat.class;
     //2、获取类的全部构造器
     Constructor[] constructors = c.getDeclaredConstructors();
     //遍历数组中的每一个构造器对象。
     for(Constructor constructor: constructors){
         System.out.println(constructor.getName()+"---> 参数个		    数:"+constructor.getParameterCount());
     }
    
     //3、获取类public修饰的空参数构造器
     Constructor constructor1 = c.getConstructor();
     System.out.println(constructor1.getName()+"---> 参数个   数:"+constructor1.getParameterCount());
            
     //4、获取private修饰的有两个参数的构造器,第一个参数String类型,第二个参数int类型
     Constructor constructor2 = c.getDeclaredConstructor(String.class,int.class);
    
  • 使用:通过构造器Constructor的方法初始化对象并返回

    • T newInstance(Object … initargs) //调用构造器,传入参数完成对象初始化并返回
    • void setAccessible(boolean flag) //设置为true,表示暴力反射

    代码示例:

    constructor2.setAccessible(true)
    Cat c = (Cat)constructor2.newInstance("加菲猫"2)
    

1.3反射获取成员变量&使用

  • Class类获取成员变量的方法

在这里插入图片描述

  • 代码示例:

    //1.反射第一步,获取类的Class对象
    Class c = Cat.class
    //2.获取类的全部成员变量数组
    Field[] fields = c.getDeclaredFields();
    
    //3.获取某个成员变量
    Field fName = c.getDeclaredField("name")
    System.out.println(fName.getName() + "----" + fName.getType())
    
  • 使用

    • void set(Object obj,Object value) //赋值
    • Object get(Object obj) //取值
    • void setAccessible(boolean flag)//设置为true,表示暴力反射

    代码示例:

     fName.setAccessible(true)
     fName.set(cat,"加菲猫") //赋值
     String name = (String) fName.get(cat) //取值
    

1.4 反射获取成员方法

  • Class类获取成员方法的方法
    在这里插入图片描述

  • 代码示例

在这里插入图片描述

  • 使用

    • Object invoke(Object obj,Object … args)//执行方法
    • void setAccessible(boolean flag) //设置为true,表示暴力反射

    代码示例:

    //1、反射第一步:先获取到Class对象
    Class c = Cat.class;
    
    //2、获取类中的全部成员方法
    Method[] methods = c.getDecalaredMethods();
    
    //3、获取private修饰的run方法,得到Method对象
    Method run = c.getDecalaredMethod("run");
    //执行run方法,在执行前需要取消权限检查
    Cat cat = new Cat();
    run.setAccessible(true);
    Object rs1 = run.invoke(cat);
    System.out.println(rs1)
    
    //5、获取private 修饰的eat(String name)方法,得到Method对象
    Method eat = c.getDeclaredMethod("eat",String.class);
    eat.setAccessible(true);
    Object rs2 = eat.invoke(cat,"鱼儿");
    System.out.println(rs2)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值