`
yimlin
  • 浏览: 139478 次
  • 性别: 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技术,反射与动态代理

    本主题将深入探讨JVM技术,特别是反射与动态代理这两个关键特性。 一、JVM技术 1. 类加载机制:JVM通过类加载器(ClassLoader)来加载.class文件,分为启动类加载器、扩展类加载器和应用程序类加载器。类的加载...

    反射-动态代理-注解

    在Java编程语言中,反射、动态代理和注解是三个重要的高级特性,它们极大地扩展了Java的灵活性和可扩展性。下面将详细讲解这三个概念及其应用。 **反射(Reflection)** 反射是Java提供的一种能力,允许程序在运行时...

    JAVA的反射机制与动态代理

    Java的反射机制与动态代理是Java编程中两个非常重要的高级特性,它们在实际开发中有着广泛的应用。反射机制允许程序在运行时动态地获取类的信息并操作类的对象,而动态代理则提供了一种创建和控制代理对象的方式,...

    Java深度历险(七)——Java反射与动态代理.pdf

    在"Java深度历险(七)——Java反射与动态代理"中,我们探讨了如何利用反射API获取类的运行时信息以及如何动态地执行类的操作。 首先,反射API的核心是`java.lang.Class`类,它代表了Java程序中的每一个类型。通过`...

    Java深度历险(七)——Java反射与动态代理.docx

    Java反射与动态代理是Java语言中的高级特性,它们允许程序在运行时检查和操作类、对象及它们的成员。在本文中,我们将深入探讨这两个概念,了解如何使用反射API进行类的动态操作,并掌握动态代理的基本用法及其在AOP...

    Core.Java基础教程_13.高级编程-反射、动态代理与Annotation.pdf

    动态代理是反射的一部分,通过`Proxy.newProxyInstance()`方法可以创建一个代理对象,该对象可以拦截调用并执行自定义逻辑。代理对象可以用来处理如缓存、事务管理、日志记录等跨切面的职责。 最后,`Annotation`...

    java反射之动态代理

    总的来说,Java反射和动态代理提供了一种强大的工具,允许我们在运行时探索和操作类的结构,实现代码的动态扩展和灵活控制。这对于构建可扩展、可维护的系统至关重要,尤其是在需要实现复杂逻辑如日志记录、性能监控...

    Java静态代理和动态代理

    四、静态代理与动态代理的比较 1. **灵活性**:动态代理比静态代理更灵活,因为不需要预先编写代理类的源代码,可以适应接口的变化。 2. **代码量**:静态代理需要为每个委托类编写单独的代理类,如果委托类很多,会...

    Android 反射注解与动态代理综合使用详解

    在Android开发中,反射、注解和动态代理是三个非常重要的高级特性,它们极大地提高了代码的灵活性和可维护性。接下来我们将深入探讨这三个概念以及它们的综合应用。 反射(Reflection)是Java提供的一种机制,允许...

    JavaSE常见面试题-高级反射-JVM篇.pdf

    本文档涵盖了JavaSE中高级反射和JVM相关的知识点,包括Java中的反射机制、动态代理、设计模式、回收机制、JDK7和JDK8的区别、Jvm虚拟机原理等。 一、 Java中的反射机制 Java中的反射机制是指可以在运行时inspect和...

    输出JDK和CGLib动态代理产生的class文件.zip

    通过分析这些class文件,我们可以更深入地理解Java虚拟机(JVM)是如何执行动态代理的。同时,这两个项目也为我们提供了一个实践和调试动态代理的平台,有助于提升我们的编程技能和对Java底层机制的理解。

Global site tag (gtag.js) - Google Analytics