`
lliang54
  • 浏览: 4361 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

反射的原理粗略分析

 
阅读更多

 

代码片段:

     Method[] method = Pow3.class.getDeclaredMethods();

method[0].invoke(new Pow3(), 1);

此段代码通过反射获取类所定义的方法,具体流程是:通过class 的 getDeclaredMethods 方法获取类的定义的方法,

   @CallerSensitive
    public Method[] getDeclaredMethods() throws SecurityException {
        // be very careful not to change the stack depth of this
        // checkMemberAccess call for security reasons
        // see java.lang.SecurityManager.checkMemberAccess
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        return copyMethods(privateGetDeclaredMethods(false));
    }

 主要逻辑在privateGetDeclaredMethods方法和copyMethods 方法中现在咱们来一个个分析该方法

 private Method[] privateGetDeclaredMethods(boolean publicOnly) {
        checkInitted();
        Method[] res;
        //获取反射属性的列表
        ReflectionData<T> rd = reflectionData();
        if (rd != null) {
            res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods;
            if (res != null) return res;
        }
        // No cached value available; request value from VM
        res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
        if (rd != null) {
            if (publicOnly) {
                rd.declaredPublicMethods = res;
            } else {
                rd.declaredMethods = res;
            }
        }
        return res;
    }

  此方法中有个ReflectionData 数据结构,是存放反射的类相关的方法,属性信息

   static class ReflectionData<T> {
        volatile Field[] declaredFields;
        volatile Field[] publicFields;
        volatile Method[] declaredMethods;
        volatile Method[] publicMethods;
        volatile Constructor<T>[] declaredConstructors;
        volatile Constructor<T>[] publicConstructors;
        // Intermediate results for getFields and getMethods
        volatile Field[] declaredPublicFields;
        volatile Method[] declaredPublicMethods;
        // Value of classRedefinedCount when we created this ReflectionData instance
        final int redefinedCount;

        ReflectionData(int redefinedCount) {
            this.redefinedCount = redefinedCount;
        }
    }

 

 //获取反射属性的列表
        ReflectionData<T> rd = reflectionData();

 

 

 // Lazily create and cache ReflectionData
    private ReflectionData<T> reflectionData() {
      //先从缓存中取 并放到软引用中,这样有利于在内存不足的情况下jvm 回收
        SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
        int classRedefinedCount = this.classRedefinedCount;
        ReflectionData<T> rd;
        if (useCaches &&
            reflectionData != null &&
            (rd = reflectionData.get()) != null &&
            rd.redefinedCount == classRedefinedCount) {
            return rd;
        }
        // else no SoftReference or cleared SoftReference or stale ReflectionData
        // -> 如果缓存中没有从VM里面拿
        return newReflectionData(reflectionData, classRedefinedCount);
    }

 

 private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
                                                int classRedefinedCount) {
        if (!useCaches) return null;

        while (true) {
            ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
            // 通过cas 算法,从vm 中拿取数据
            if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
                return rd;
            }
            // else retry
            oldReflectionData = this.reflectionData;
            classRedefinedCount = this.classRedefinedCount;
            if (oldReflectionData != null &&
                (rd = oldReflectionData.get()) != null &&
                rd.redefinedCount == classRedefinedCount) {
                return rd;
            }
        }
    }

   这个是读取反射对象的大概过程,接下来分析copyMethods 

  private static Method[] copyMethods(Method[] arg) {
        Method[] out = new Method[arg.length];
        ReflectionFactory fact = getReflectionFactory();
        for (int i = 0; i < arg.length; i++) {
            out[i] = fact.copyMethod(arg[i]);
        }
        return out;
    }

 fact.copyMethod 方法最终调用的是method 的copy 所以说。通过反射获取method 每次都是生成一个对象的拷贝,是一个新的method 对象,

   Method copy() {
        // This routine enables sharing of MethodAccessor objects
        // among Method objects which refer to the same underlying
        // method in the VM. (All of this contortion is only necessary
        // because of the "accessibility" bit in AccessibleObject,
        // which implicitly requires that new java.lang.reflect
        // objects be fabricated for each reflective call on Class
        // objects.)
        Method res = new Method(clazz, name, parameterTypes, returnType,
                                exceptionTypes, modifiers, slot, signature,
                                annotations, parameterAnnotations, annotationDefault);
        res.root = this;
        // Might as well eagerly propagate this if already present
        res.methodAccessor = methodAccessor;
        return res;
    }

   其实对method 的方法调用最终是methodAccessor的invoke 调用 ,也是委托给MethodAccessorImpl 的invoke 调用

 public Object invoke(Object paramObject, Object[] paramArrayOfObject)
   throws IllegalArgumentException, InvocationTargetException
 {
     return this.delegate.invoke(paramObject, paramArrayOfObject);
 }

 再委托给NativeMethodAccessorImpl 的invoke 方法

 

 public Object invoke(Object paramObject, Object[] paramArrayOfObject)
    throws IllegalArgumentException, InvocationTargetException
 {
    if (++this.numInvocations > ReflectionFactory.inflationThreshold()) {
    MethodAccessorImpl localMethodAccessorImpl = (MethodAccessorImpl)new MethodAccessorGenerator().generateMethod(this.method.getDeclaringClass(), this.method.getName(), this.method.getParameterTypes(), this.method.getReturnType(), this.method.getExceptionTypes(), this.method.getModifiers());

     this.parent.setDelegate(localMethodAccessorImpl);
     }
    
    return invoke0(this.method, paramObject, paramArrayOfObject);
   }

此段逻辑是当判断 numInvocations>15次调用会生成MethodAccessorImplXXX字节码,如果小于15次就直接调用原生的private static native Object invoke0(Method paramMethod, Object paramObject, Object[] paramArrayOfObject) 方法进行方法的调用。 需要注意的是,由于numInvocations 不是线程安全的。所以在高并发的情况下。会生成很多无用的类。如果并发1000个,会有999个是无用的,会增加perm 区满,导致永久区溢出,

 

 

 

分享到:
评论

相关推荐

    一种粗略的普通摄像头的深度信息提取方法 c 源码

    本篇将围绕"一种粗略的普通摄像头的深度信息提取方法 c 源码"这一主题,深入解析这一技术及其C语言实现的源码。 首先,我们需要理解深度信息的来源。在自然环境中,光线从物体表面反射到摄像头,摄像头接收到这些...

    岛津SPM-9500原子力显微镜原理及操作流程.pptx

    6. 粗略定位系统、防震防噪声系统、计算机控制系统、数据处理软件、样品探测环境控制系统以及显微及CCD摄像系统等辅助系统,确保整个设备的正常运作和数据获取。 操作AFM时,需考虑样品要求,例如样品表面应平整,...

    IT认证-光纤光学总复习-2015..docx

    关于SIOF和GIOF的错误观点包括:SIOF不是反射型光纤,而是利用全反射原理工作;GIOF的通信容量并不一定比SIOF大,这取决于多种因素,如模数量、信号处理技术等;SIOF和GIOF都能支持线偏振模,只是GIOF更容易维持线...

    原子力显微镜原理及操作流程讲义.pptx

    形变的检测通常依赖于激光束的反射,利用光杠杆效应,即使是微小的悬臂形变也能被精确测量。 3. AFM的主要构件包括激光系统、微悬臂系统、压电扫描器和光电探测器等。激光系统提供稳定的光源,微悬臂系统是关键的力...

    wifi 人体定位Multi-Person Localization via RF Body Reflections

    - **多径效应处理**:通过复杂的信号分析算法处理室内环境中的多径反射问题,提高定位精度。 - **手势识别**:通过对特定手势产生的信号特征进行分析,实现对指向等手势的识别。 #### 实验验证与结果 研究人员构建...

    名企逻辑题目.doc

    这个问题涉及到光学中的反射原理。实际上,镜子并不改变上下或左右,而是改变了前后方向,看起来像是左右颠倒。 ### 9. 水量测量问题 **题目描述:** 使用3公升和5公升的提桶准确称出4公升的水。 **解答分析:** ...

    行业资料-电子功用-光电系统跟瞄精度测量装置光路调校方法的说明分析.rar

    它的工作原理是通过光学元件对目标发射或反射的光进行采集,然后由光电探测器转换为电信号,再经过信号处理电路解析,最终得到与光信号相关的信息。 二、跟瞄精度的重要性 跟瞄精度是光电系统的核心性能指标,它...

    行业分类-设备装置-一种精粗结合的光学表面缺陷的检测方法及装置.zip

    1. **光学表面缺陷检测**:这是整个话题的核心,涉及如何发现和分析光学表面上的微小瑕疵,如划痕、污染、不平整等,这些缺陷可能影响光的反射、折射或透射性能。 2. **精粗结合的检测策略**:这种方法可能是指先用...

    Fabry-Perot测风干涉仪数据处理.pdf

    当一束激光经过一个具有薄膜的法布里-珀罗干涉仪时,光会被薄膜反射,形成相位差。这个相位差与大气中的风速和方向密切相关,因为风会影响光通过大气层时的传播路径。通过精确分析干涉条纹的变化,可以反演出中高层...

    无线电导航讲义

    讲义中可能涵盖了无线电信号的频率、波长、传播模式(如直线传播、地面反射等)以及信号衰减等相关概念。 2. 经典无线电导航系统 讲义会讲解传统的无线电导航系统,如VOR(甚高频全向信标)、DME(测距仪)和ADF...

    网络游戏-一种测量网线阻抗的装置和方法、以及网络设备.zip

    1. 使用专业仪表:如网络分析仪、阻抗分析仪等,它们能够精确测量网线的特性阻抗,提供详细的测试报告。 2. 电阻测试:通过测量网线两端的电阻值,间接推算阻抗,但这方法通常不够精确,仅适用于粗略估计。 四、...

    基于分布式光纤传感技术的封闭空间火源精确定位方法研究.pdf

    分布式光纤传感技术利用这一原理,通过分析后向拉曼散射信号中的温度信息,实现对分布式区域的实时温度监测。 在封闭空间火源精确定位方法研究中,文章提出了一种基于拉曼散射的分布式光纤传感技术。该技术利用...

    分布式光纤温度传感渗漏监测技术研究进展 (2).pdf

    该技术工作原理基于光时域反射(OTDR)技术,通过测量沿传感光纤传播的脉冲激光的时间和强度,实现对沿线温度变化的实时监测。其基本原理是,当光纤沿线发生温度变化时,光纤材料的折射率和长度会发生相应变化,进而...

    电信设备-大型工作室环境中的摄像机的被动定位信息.zip

    1. 被动定位原理:摄像机的被动定位技术主要依赖于对环境中电磁信号的捕获和分析。它并不主动发射信号,而是通过接收周围设备(如Wi-Fi、蓝牙或移动通信设备)发射的无线电信号来确定自身的地理位置。这种技术具有低...

    伪距单点定位PPT学习教案.pptx

    伪距单点定位是基础的 GNSS 定位技术,依赖于伪距观测方程的线性化处理和观测数据的精确分析。虽然可以提供粗略的地理位置,但其精度受到多种因素的影响。在实际应用中,常常会结合多颗卫星的观测数据和更复杂的定位...

    sum_difference.rar_SUM_幅度和差测角_测角跟踪_目标测角_目标跟踪

    这两个信号可以是同一个目标的不同反射,也可以是两个不同目标的回波。通过对这两个信号进行幅度和差处理,我们可以提取出关于目标位置和运动状态的信息。 幅度和差测角的基本原理是利用两个天线(或一个双极化天线...

Global site tag (gtag.js) - Google Analytics