`
yimlin
  • 浏览: 137172 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

JVM,反射与动态代理

阅读更多

<!----> <o:p>(从csdn的blog转来) </o:p>

Java 程序的工作机制: Java 对象都以单独的 class 文件存在, java 虚拟机将其载入并执行其虚拟机指令。

<o:p> </o:p>

Java 虚拟机查找这些 java 对象:

java 虚拟机根据 class path 来查找 java 对象,而虚拟机的 class path 又分为三层:

bootstrap sun.boot.class.path

extension: java.ext.dirs

application: java.class.path

三个 class path 各有对应的 classloader 。由上而下形成父子关系

当程序中调用 new 指令,或者 ClassLoader.load 方法时。其顺序如下:

1.       首先查看 application classloader 中是否已有对应的 class 缓存,如果有则返回,并根据 class 分配内存。如果没有,接下一步。

2.       首先查看 extension classloader 中是否已有对应的 class 缓存,如果有则返回,并根据 class 分配内存。如果没有,接下一步。

3.       首先查看 bootstrap classloader 中是否已有对应的 class 缓存,如果有则返回,并根据 class 分配内存。如果没有,接下一步。

4.       bootstrap classloader 在其 class path 中试图加载该 class ,如果有,则将该 class 放入 cache 中,并返回。如果没有,接下一步。

5.       extension classloader 在其 class path 中试图加载该 class ,如果有,则将该 class 放入 cache 中,并返回。如果没有,接下一步。

6.       application classloader 在其 class path 中试图加载该 class ,如果有,则将该 class 放入 cache 中,并返回。如果没有,则抛出 ClassNotFound exception

<o:p> </o:p>

Java 虚拟机加载这些 java 对象:

每个 java 虚拟机都在其启动时产生一个唯一的 class heap ,并把所有的 class instance 都分配在其中。其中每个类实例的信息又分两部分, fields 域和 methods 域。每个类实例各自拥有 fields ,但同一个类的不同实例共享 methods

<o:p> </o:p>

反射

JVM 对反射的处理

简单例子代码:

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.InvocationTargetException;

import java.io.IOException;

<o:p> </o:p>

public class <!----><st1:place w:st="on">Main</st1:place> {

    public static void main(String[] args){

        TempImpl t1 = new TempImpl("temp1");

        try {

            Method t1Talk = t1.getClass().getMethod("Talk", new Class[0]) ;

            t1Talk.invoke(t1, null);

        } catch (NoSuchMethodException e) {

            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

        } catch (IllegalAccessException e) {

            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

        } catch (InvocationTargetException e) {

            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

        }

        try {

            System.in.read();

        } catch (IOException e) {

            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

        }

    }

}

复杂例子代码:

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.InvocationTargetException;

import java.io.IOException;

<o:p> </o:p>

public class <st1:place w:st="on">Main</st1:place> {

    public static void main(String[] args){

        TempImpl t1 = new TempImpl("temp1");

        TempImpl t2 = new TempImpl("temp2");

        Temp2 temp2 = new Temp2();

        try {

            Method t1Talk = t1.getClass().getMethod("Talk", new Class[0]) ;

            Method t2Talk = t2.getClass().getMethod("Talk", new Class[0]) ;

            t1Talk.invoke(t2, null);

            t2Talk.invoke(t1, null);

            if(t1Talk.equals(t2Talk)){

                System.out.println("equals");

            }

           else{

                System.out.println("not equals");

            }

            if(t1Talk==t2Talk){

                System.out.println("ref equals");

            }

           else{

                System.out.println("ref not equals");

            }

            t2Talk.invoke(temp2, null);

        } catch (NoSuchMethodException e) {

            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

        } catch (IllegalAccessException e) {

            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

        } catch (InvocationTargetException e) {

            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

        }

        try {

            System.in.read();

        } catch (IOException e) {

            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

        }

    }

}

<o:p> </o:p>

分析: java 虚拟机把每个 methods 当作一个执行单元。该执行单元带有两种签名:类签名和属性签名( public static 等)。 反射的第一步,验证签名的合法性。验证通过后,顺序执行该 method 中的指令,当需要访问类实例的 fields 和传入参数时,由虚拟机注入。

<o:p> </o:p>

动态代理

Sun 对动态代理的说明:

一个简单例子代码:

动态代理的内部实现——代码生成:

研究 JDK 源代码,发现在 Proxy sun 实现中调用了 sun.misc.ProxyGenerator 类的 generateProxyClass( proxyName, interfaces) 方法,其返回值为 byte[] class 文件的内存类型一致。于是做如下试验:

public class  ProxyClassFile{

       public static void main(String[] args){

              String proxyName = "TempProxy";

        TempImpl t = new TempImpl("proxy");

              Class[] interfaces =t.getClass().getInterfaces();

             

              byte[] proxyClassFile = ProxyGenerator.generateProxyClass(

                  proxyName, interfaces);

        File f = new File("classes/TempProxy.class");

        try {

            FileOutputStream fos = new FileOutputStream(f);

            fos.write(proxyClassFile);

            fos.flush();

            fos.close();

        } catch (FileNotFoundException e) {

            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

        } catch (IOException e) {

            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.

        }

       }

}

运行该类,到 class 文件夹下,利用反编译技术,发现原来其采用了代码生产技术:

<o:p> </o:p>

public interface Temp{<o:p></o:p>

       public void Talk();<o:p></o:p>

       public void Run();<o:p></o:p>

}<o:p></o:p>

import java.lang.reflect.*;<o:p></o:p>

<o:p> </o:p>

public final class TempProxy extends Proxy<o:p></o:p>

    implements Temp{<o:p></o:p>

<o:p> </o:p>

    private static Method m4;<o:p></o:p>

    private static Method m2;<o:p></o:p>

    private static Method m0;<o:p></o:p>

    private static Method m3;<o:p></o:p>

    private static Method m1;<o:p></o:p>

<o:p> </o:p>

    public TempProxy(InvocationHandler invocationhandler)   {<o:p></o:p>

        super(invocationhandler);<o:p></o:p>

    }<o:p></o:p>

<o:p> </o:p>

    public final void Run()    {<o:p></o:p>

        try {<o:p></o:p>

            h.invoke(this, m4, null);<o:p></o:p>

            return;<o:p></o:p>

        }<o:p></o:p>

        catch(Error _ex) { }<o:p></o:p>

        catch(Throwable throwable)  {<o:p></o:p>

            throw new UndeclaredThrowableException(throwable);<o:p></o:p>

        }<o:p></o:p>

    }<o:p></o:p>

<o:p> </o:p>

    public final String toString(){<o:p></o:p>

        try{<o:p></o:p>

            return (String)h.invoke(this, m2, null);<o:p></o:p>

        }<o:p></o:p>

        catch(Error _ex) { }<o:p></o:p>

        catch(Throwable throwable)  {<o:p></o:p>

            throw new UndeclaredThrowableException(throwable);<o:p></o:p>

        }<o:p></o:p>

        return "";<o:p></o:p>

    }<o:p></o:p>

<o:p> </o:p>

    public final int hashCode() {<o:p></o:p>

        try {<o:p></o:p>

            return ((Integer)h.invoke(this, m0, null)).intValue();<o:p></o:p>

        }<o:p></o:p>

        catch(Error _ex) { }<o:p></o:p>

        catch(Throwable throwable){<o:p></o:p>

            throw new UndeclaredThrowableException(throwable);<o:p></o:p>

        }<o:p></o:p>

        return 123;<o:p></o:p>

    }<o:p></o:p>

<o:p> </o:p>

    public final void Talk(){<o:p></o:p>

        try{<o:p></o:p>

            h.invoke(this, m3, null);<o:p></o:p>

            return;<o:p></o:p>

        }<o:p></o:p>

        catch(Error _ex) { }<o:p></o:p>

        catch(Throwable throwable) {<o:p></o:p>

            throw new UndeclaredThrowableException(throwable);<o:p></o:p>

        }<o:p></o:p>

    }<o:p></o:p>

<o:p> </o:p>

    public final boolean equals(Object obj) {<o:p></o:p>

        try  {<o:p></o:p>

            return ((Boolean)h.invoke(this, m1, new Object[] {<o:p></o:p>

                obj<o:p></o:p>

            })).booleanValue();<o:p></o:p>

        }<o:p></o:p>

        catch(Error _ex) { }<o:p></o:p>

        catch(Throwable throwable) {<o:p></o:p>

            throw new UndeclaredThrowableException(throwable);<o:p></o:p>

        }<o:p></o:p>

        return false;<o:p></o:p>

    }<o:p></o:p>

<o:p> </o:p>

    static{<o:p></o:p>

        try{<o:p></o:p>

     m4 = Class.forName("Temp").getMethod("Run", new Class[0]);<o:p></o:p>

     m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);<o:p></o:p>

     m0 = Class.forName("java.lang.Object").getMethod("hashCode", ne

分享到:
评论

相关推荐

    JVM技术,反射与动态代理

    Java程序的工作机制:Java对象都以单独的class文件存在,java虚拟机将其载入并执行其虚拟机指令。

    复习反射利用反射机制和AOP代理模式

    reflection是一系列的API,用于表示或者处理当前JVM中的类,接口和对象. java.lang.reflect/java.lang.Class 在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

    java_反射实战代码

    调用对象的方法,与直接在源代码中的交互是一样的,但又提供了额外的在运行时候的灵活性,但反射的一个最大的弊端就是性能比较差,相同的操作,用反射API所需的时间大概比直接使用慢一两个数量级,不过现在的JVM实现...

    javaStrengthen:Java 高级特性增强。包括多线程增强、Java并发包、Java JMS技术、Java JVM技术、Java动态代理以及反射

    javaStrengthenJava 高级特性增强。包括多线程增强、Java并发包、Java JMS技术、Java JVM技术、Java动态代理以及反射。

    Windows的代理DLL,可在JNI级别上转储JVM类-C/C++开发

    简介一些Java程序使用反射通过动态加载和执行类来隐藏其代码。 您可以从内存中转储它们,但是如果它们在执行后立即被卸载怎么办? 您可以编辑rt.jar并将钩子放在各种反射方法上。 但是,如果程序直接使用本机类加载...

    Java反射学习和反射的应用场景干货都在这里

    文章目录一、Java反射定义二、Java反射机制实现1、Class对象获取2、获取class对象的摘要信息3、获取class对象的属性、方法、构造函数等三、反射的应用场景1、动态代理2、自定义注解实现日志管理 写在前面:Java反射...

    Java全方面面试题,很全

    动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架也大量使用到了反射机制。 - **优点:** 运行期类型的判断,动态加载类,提高代码灵活度。 - **缺点:** 性能瓶颈:反射相当于一...

    免费超全面的Java基础类型,容器,并发,IO流,面向对象,Web编程等代码总结

    Proxy动态代理机制详解 从整体上观察对象 网络开发 Servlet基础,生命周期执行过程 Http请求详解,握手挥手流程简介 会话跟踪技术,Session和Cookie详解 过滤器、监听器、拦截器,应用详解 Servlet 集成 C3P0

    java高级特性增强(源码展示)

    1、掌握多线程 2、掌握并发包下的队列 3、了解JMS 4、掌握JVM技术 5、掌握反射和动态代理

    cglib.jar下载

    它比使用java反射的JDK动态代理要快。 CGLIB底层:使用字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。 CGLIB缺点:对于...

    java高级特性

    java的高级特性总结,多线程的各种实现,jvm技术,以及动态代理和反射的理解

    Java面试宝典PLUS.pdf

    包括JavaSE基础(多态、异常处理、常用API、数据类型、IO操作、集合、多线程和并发库、内部类)、JavaSE高级(反射、动态代理、设计模式&回收机制、加载器、JVM基础、GC基础)、JavaWeb基础(JDBC技术、HTTP协议、...

    JAVA 2 核心技术 卷II:高级特性7th-Code

    本书是Java技术经典参考书,多年畅销不衰,第7版在保留以前版本风格的基础上,涵盖Java 2开发平台标准版J2SE 5.0的基础知识,主要内容包括面向对象程序设计、反射与代理、接口与内部类、事件监听器模型、使用Swing ...

    spring:Spring框架

    Spring 4.x ...动态代理:在程序运行期间由JVM根据反射机制动态生成的,不存在代理类的字节码文件,代理对象和目标对象的关系是在程序运行时决定的。 动态代理两种方式 JDK代理:要求目标对象必须有接口

    java内核源码-JavaCompass:「Java指南针」为你学习Java指明方向。内容涵盖互联网Java工程师所需要掌握的核心知识,涉及J

    动态代理 JDK8新特性 集合容器 多线程与并发 Spring SpringMVC SpringBoot Mybatis 数据结构与算法 入门基础 基础数据结构 数组&链表 数组&链表进阶 栈 队列 算法思想 数论&枚举&递归&分治&回溯 排序及其源码实现 ...

    大厂面试专栏,冲击大厂必备

    ORM,动态SQL、动态代理 第十篇:Spring 那点破事!IOC、AOP、生命周期、动态代理、设计模式 第十一篇:Spring Boot !starter组件、JPA、定时任务、全局异常 第十二篇:Spring Cloud !Gateway、注册发现、Hystrix...

    JAVA高并发高性能高可用高扩展架构视频教程

    揭开springAOP神秘面纱(动态代理) Mysql性能优化之索引优化 写实现Tomcat服务器 移动后台端框架设计 公司级框架原理解析 解密公司内部框架开发(打造属于自己的专属框架) 手写Tomca之深度解析动态资源请求原理 深度...

    JAVA中级书籍

    反射机制;多线程;IO/NIO; 网络编程;常用数据结构和相关算法。 2、对面向对象的软件开发思想有清晰的认识、熟悉掌握常用的设计模式;设计模式;单例模式;工厂模式;代理模式;模板方法模式;责任链模式等。 3...

    【Java入门知识图谱】帮助Java初学者成长

    【对线面试官】Java反射 && 动态代理 爪哇 【对线面试官】多线程基础 【对线面试官】 CAS 【对线面试官】同步进行 【对线面试官】AQS&&ReentrantLock 【对线面试官】线程池 【对线面试官】ThreadLocal 【对线面试官...

    疯狂JAVA讲义

    1.3.2 Java程序的运行机制和JVM 6 1.4 开发Java的准备 7 1.4.1 安装JDK 8 学生提问:不是说JVM是运行Java程序的虚拟机吗?那JRE和JVM的关系是怎样的呢? 8 学生提问:为什么不安装公共JRE系统呢? 9 1.4.2 设置...

Global site tag (gtag.js) - Google Analytics