java程序的工作机制:java对象都以单独的class文件存在,java虚拟机将其载入并执行其虚拟机指令。
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。
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 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 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当作一个执行单元。该执行单元带有两种签名:类签名和属性签名(public,static等)。 反射的第一步,验证签名的合法性。验证通过后,顺序执行该method中的指令,当需要访问类实例的fields和传入参数时,由虚拟机注入。
动态代理
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文件夹下,利用反编译技术,发现原来其采用了代码生产技术:
public interface temp{ public void talk(); public void run(); } |
import java.lang.reflect.*; public final class tempproxy extends proxy implements temp{ private static method m4; private static method m2; private static method m0; private static method m3; private static method m1; public tempproxy(invocationhandler invocationhandler) { super(invocationhandler); } public final void run() { try { h.invoke(this, m4, null); return; } catch(error _ex) { } catch(throwable throwable) { throw new undeclaredthrowableexception(throwable); } } public final string tostring(){ try{ return (string)h.invoke(this, m2, null); } catch(error _ex) { } catch(throwable throwable) { throw new undeclaredthrowableexception(throwable); } return ""; } public final int hashcode() { try { return ((integer)h.invoke(this, m0, null)).intvalue(); } catch(error _ex) { } catch(throwable throwable){ throw new undeclaredthrowableexception(throwable); } return 123; } public final void talk(){ try{ h.invoke(this, m3, null); return; } catch(error _ex) { } catch(throwable throwable) { throw new undeclaredthrowableexception(throwable); } } public final boolean equals(object obj) { try { return ((boolean)h.invoke(this, m1, new object[] { obj })).booleanvalue(); } catch(error _ex) { } catch(throwable throwable) { throw new undeclaredthrowableexception(throwable); } return false; } static{ try{ m4 = class.forname("temp").getmethod("run", new class[0]); m2 = class.forname("java.lang.object").getmethod("tostring", new class[0]); m0 = class.forname("java.lang.object").getmethod("hashcode", new class[0]); m3 = class.forname("temp").getmethod("talk", new class[0]); m1 = class.forname("java.lang.object").getmethod("equals", new class[] { class.forname("java.lang.object") }); } catch(nosuchmethodexception nosuchmethodexception) { throw new nosuchmethoderror(nosuchmethodexception.getmessage()); } catch(classnotfoundexception classnotfoundexception) { throw new noclassdeffounderror(classnotfoundexception.getmessage()); } } } |
闽公网安备 35060202000074号