初探Java 函数反射

问题:

  1. Java 的函数反射性能真的差吗?
  2. Java 实现反射的方式?

Java 的函数评估反射性能问题之前,首先先了解java中的反射方式。
在这里插入图片描述

此为Java method 的源码,其关键实现为 sun.reflect.MethodAccessor
类继承关系
在这里插入图片描述

DelegatingMethodAccessorImpl 采用委托形式实现,其本身不包含业务逻辑

class DelegatingMethodAccessorImpl extends MethodAccessorImpl {
    private MethodAccessorImpl delegate;

    DelegatingMethodAccessorImpl(MethodAccessorImpl delegate) {
        setDelegate(delegate);
    }

    public Object invoke(Object obj, Object[] args)
        throws IllegalArgumentException, InvocationTargetException
    {
        return delegate.invoke(obj, args);
    }

    void setDelegate(MethodAccessorImpl delegate) {
        this.delegate = delegate;
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Java 正常情况 反射执行首先采用native 方式,然儿 java在此做了优化,如下

在这里插入图片描述
在这里插入图片描述

Native 相对来说 依赖于jni 来执行,相对原生的java 性能较差,故在常用的要反射执行的函数默认前16次执行 采用 native 方式。后java 为其动态生成反射执行类
Arthas 反射运行代码
sc sun.reflect.MethodAccessor 查看所有子类

[arthas@25904]$ sc sun.reflect.MethodAccessor 
sun.reflect.DelegatingMethodAccessorImpl 
sun.reflect.GeneratedMethodAccessor1 
sun.reflect.GeneratedMethodAccessor10 
....

sun.reflect.GeneratedMethodAccessor65 查看java 生成的代理类源码

/* 
* Decompiled with CFR. 
*  
* Could not load the following classes: 
*  pook.action.logic.simple.MciLogicController 
*  pook.action.msg.request.simple.MciGameProgressLogRequest 
*/ 
package sun.reflect; 

import java.lang.reflect.InvocationTargetException; 
import pook.action.logic.simple.MciLogicController; 
import pook.action.msg.request.simple.MciGameProgressLogRequest; 
import sun.reflect.MethodAccessorImpl; 

public class GeneratedMethodAccessor86 
extends MethodAccessorImpl { 
   /* 
    * Loose catch block 
    * Enabled aggressive block sorting 
    * Enabled unnecessary exception pruning 
    * Enabled aggressive exception aggregation 
    * Lifted jumps to return sites 
    */ 
   public Object invoke(Object object, Object[] arrobject) throws InvocationTargetException { 
       if (object == null) { 
           throw new NullPointerException(); 
       } 
       MciLogicController mciLogicController = (MciLogicController)object; 
       if (arrobject.length != 1) { 
           throw new IllegalArgumentException(); 
       } 
       MciGameProgressLogRequest mciGameProgressLogRequest = (MciGameProgressLogRequest)arrobject[0]; 
       try { 
           mciLogicController.mciGameProgressLogLogic(mciGameProgressLogRequest); 
           return null; 
       } 
       catch (Throwable throwable) { 
           throw new InvocationTargetException(throwable); 
       } 
       catch (ClassCastException | NullPointerException runtimeException) { 
           throw new IllegalArgumentException(super.toString()); 
       } 
   } 
} 

前期函数反射执行 采用jni 方式相对性能低于原生的 java调用方式,后期使用动态生成的java 去执行,无异于原生方式执行。
3. 为什么第一次就采用动态生成代理类?
代理类的的生成相对较耗时,而在大多数的反射执行仅为一两次,故费时生成代理类得不偿失。
4. Java 生成代理类的次数可以动态设置吗?
可以。手动指定 sun.reflect.noInflation 可以自行修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值