Java反射的基本概念

什么是反射机制?

反射是在运行状态中,动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制
对于任意一个类,都能够知道这个类的所有属性方法
对于任意一个对象,都能够调用它的任意一个属性方法

Using java reflection we can inspect a class, interface, enum, get their structure, methods and fields information at runtime even though class is not accessible at compile time.
eg:String 有不可变性,以通过反射技术修改其值


类:用来抽象描述一组对象,从对象中抽取出来公有特征行为
反射:用来抽象描述一组类,所有的类也具有相同的特征:

包,类名字,继承关系,实现接口,属性,方法,构造方法,块,内部类 ,注解,权限修饰符,特征修饰符,抛出异常


反射常用的方法


反射使用的步骤

正常的调用

Apple apple = new Apple();
apple.setPrice(5);
apple.getPrice()

使用反射调用

Class clz = Class.forName("com.practise.api.Apple");

# 创建对象
Constructor appleConstructor = clz.getConstructor();
Object appleObj = appleConstructor.newInstance();

# 调用set方法
Method setPriceMethod = clz.getMethod("setPrice", int.class);
setPriceMethod.invoke(appleObj, 14);

# 调用get方法
Method getPriceMethod = clz.getMethod("getPrice");
getPriceMethod.invoke(appleObj);

常见反射机制的应用

1、JDBC 的数据库的连接
2、Spring 框架里使用xml的配置模式

Spring 通过 XML 配置模式装载 Bean 的过程:
1、程序内所有 XMLProperties 配置文件加载入内存中
2、解析xmlproperties的内容,得到对应实体类的字节码字符串,及相关的属性信息
3、使用反射机制,根据这个字符串获得某个类的Class实例
4、动态配置实例的属性

Spring使用反射的好处:
1、多种方式创建对象,不仅仅new
2、 方便维护,有改变直接改配置文件
3、有时为了适应某些需求,Java类里面不一定能直接调用另外的方法,可以通过反射机制来实现。


反射机制的原理

Class actionClass=Class.forName(MyClass);               进行类加载

Object action=actionClass.newInstance();               	  1. 权限检测,如果不通过直接抛出异常
														  2. 查找无参构造器,并将其缓存起来
														  3. 调用无参构造方法,生成实例并返回
														  
Method method = actionClass.getMethod(“myMethod”,null);   获取Method对象

method.invoke(action,null);                               调用invoke()方法 

获取Method对象

Class对象是在加载类时由JVM构造的
JVM为每个类管理一个独一无二的Class对象
Class对象里维护着该类的所有Method,Field,Constructor的cache,这份cache也可以被称作根对象

在这里插入图片描述


调用invoke方法的流程如下:

在这里插入图片描述

调用Method.invoke之后,会直接去调MethodAccessor.invokeMethodAccessor所有同名method共享的一个实例,由ReflectionFactory创建。


以调用 MyClass.myMethod(String s) 为例,生成出的MethodAccessorImpl字节码翻译成Java代码大致如下:

public class GeneratedMethodAccessor1 extends MethodAccessorImpl {    
    public Object invoke(Object obj, Object[] args)  throws Exception {
        try {
            MyClass target = (MyClass) obj;
            String arg0 = (String) args[0];
            target.myMethod(arg0);
        } catch (Throwable t) {
            throw new InvocationTargetException(t);
        }
    }
}

创建机制采用了一种名为inflation的方式(JDK1.4之后)

如果该方法的累计调用次数<=15,会创建出NativeMethodAccessorImpl,它的实现就是直接调用native方法实现反射;
如果该方法的累计调用次数>15,会由java代码创建出字节码组装而成的MethodAccessorImpl
是否采用inflation和15这个数字都可以在jvm参数中调整

参考:深入理解java反射原理


反射机制的优缺点

优点:灵活性
缺点:解析字节码,解析内存中对象,性能较低

其解决方案是:
1、通过setAccessible(true)关闭JDK的安全检查来提升反射速度
2、多次创建一个类的实例时,有缓存会快很多
3、ReflflectASM工具类,通过字节码生成的方式加快反射速度

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值