JVM技术,反射与动态代理(一)

    技术2022-05-11  38

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

     

    看JVM技术,反射与动态代理(二)

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

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

    bootstrapsun.boot.class.path

    extension: java.ext.dirs

    application: java.class.path

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

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

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

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

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

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

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

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

     

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

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

     

    反射

    JVM对反射的处理

    简单例子代码:

    import java.lang.reflect.InvocationHandler;

    import java.lang.reflect.Method;

    import java.lang.reflect.InvocationTargetException;

    import java.io.IOException;

     

    public class Main {

        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;

     

    public class Main {

        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.

            }

        }

    }

     

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

     

    最新回复(0)