Java反射机制

Java反射原理图

image-20231130161209461

image-20231130170735633

Java反射机制可以完成

  1. 在运行时判断任意一个对象所属的类
  2. 在运行时构造任意一个对象的类
  3. 在运行时得到任意一个类所具有的成员变量和方法
  4. 在运行时调用任意一个对象的成员变量和方法
  5. 生成动态代理

反射的优点和缺点

  1. 优点:可以动态的创建和使用对象(也是底层框架的核心),使用灵活,没有反射机制,底层框架就失去技术支撑
  2. 缺点:使用反射基本是解释执行,对执行速度又有影响

反射调用优化

  1. Method和Field,Constructor对象都有setAccessible()方法
  2. setAccessible()作用是启动和禁用访问安全检查的开关
  3. 参数值为True时,反射的对象在使用时取消访问检查,提高反射的效率。为False时则表示反射的对象执行访问检查

Class类对象

  1. Class也是类,因此也继承Object类
  2. Class类对象不是new出来的,而是系统创建的
  3. 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
  4. 每个类的实例都会记得自己是由哪个Class实例所生成
  5. 每个Class对象可以完整的得到一个类的完整结构,通过一系列API
  6. Class对象是存放在堆里的

Class类的常用方法

获取Class对象方式

  1. Class.forName()
  2. 类名.class,应用场景:用于传递参数
  3. 对象.getClass 应用场景:已知某个类的实例,通过实例获得Class对象
  4. 其他方式:通过类加载器获取对象 先 对象.getClass.getClassLoader()得到类加载器 再 类加载器.loadClass(classPath)

反射创建对象实例

    Class<?> aClass = Class.forName("yang.pojo.Stu");       //加载类,返回Class对象
    Stu stu1 = (Stu) aClass.newInstance();                  //默认调用无参构造方法
    System.out.println(stu1);
 /*   通过有参构造创建实例!!!这里有参构造为public属性*/
    Constructor<?> constructor = aClass.getConstructor(String.class, String.class, String.class);
    Stu stu2 = (Stu) constructor.newInstance("ysf","20","男");
    System.out.println(stu2);
/*    通过有参构造创建实例!!1这里有参构造为private属性/*/
    Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(String.class, String.class, String.class);
    declaredConstructor.setAccessible(true);    //暴力破解
    Stu stu3 =(Stu) declaredConstructor.newInstance("ysf", "20", "nan");
    System.out.println(stu3);

通过反射访问类中的属性

image-20231203143339641

​ 案例:

public class FieldTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
        Class<?> aClass = Class.forName("yang.pojo.Stu");   //加载类,获得加载类对象
        Stu stu =(Stu) aClass.newInstance();    //通过无参构造实例化对象

        Field[] fields = aClass.getFields();    //只能获得公有属性

        Field[] declaredFields = aClass.getDeclaredFields();    //获得所有属性(公私有都可以)


        Field name = aClass.getDeclaredField("name");   //获得name属性,此时为私有属性
        name.setAccessible(true);   //将私有属性name爆破
        name.set(stu,"bhdx");           //.set()方法设置name属性值
        String n = name.get(stu).toString();        //.get()方法访问name属性值
        System.out.println(n);
    }
}

通过反射访问类中的方法

image-20231203144812207

​ 案例:

public class MethodTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<?> aClass = Class.forName("yang.pojo.Stu");   //加载类,获得类对象
        Stu stu = (Stu)aClass.newInstance();            //无参方法实例化对象

        aClass.getMethods();    //只能获得公有方法
        aClass.getDeclaredMethods();     // 获得所有方法,公私有方法都可
        Method info = aClass.getDeclaredMethod("info"); //此时info方法为private属性
        info.setAccessible(true);   //强制爆破
        info.invoke(stu);       //调用方法
    }
}
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值