posts - 0,  comments - 17,  trackbacks - 0

          JavaVM,反射與動(dòng)態(tài)代理



          Java程序的工作機(jī)制:Java對(duì)象都以單獨(dú)的class文件存在,java虛擬機(jī)將其載入并執(zhí)行其虛擬機(jī)指令。



          Java虛擬機(jī)查找這些java對(duì)象:

          java虛擬機(jī)根據(jù)class path來(lái)查找java對(duì)象,而虛擬機(jī)的class path又分為三層:

          bootstrap:sun.boot.class.path

          extension: java.ext.dirs

          application: java.class.path

          三個(gè)class path各有對(duì)應(yīng)的classloader。由上而下形成父子關(guān)系

          當(dāng)程序中調(diào)用new指令,或者ClassLoader.load方法時(shí)。其順序如下:

          1. 首先查看application的classloader中是否已有對(duì)應(yīng)的class緩存,如果有則返回,并根據(jù)class分配內(nèi)存。如果沒(méi)有,接下一步。

          2. 首先查看extension的classloader中是否已有對(duì)應(yīng)的class緩存,如果有則返回,并根據(jù)class分配內(nèi)存。如果沒(méi)有,接下一步。

          3. 首先查看bootstrap的classloader中是否已有對(duì)應(yīng)的class緩存,如果有則返回,并根據(jù)class分配內(nèi)存。如果沒(méi)有,接下一步。

          4. 由bootstrap的classloader在其class path中試圖加載該class,如果有,則將該class放入cache中,并返回。如果沒(méi)有,接下一步。

          5. 由extension的classloader在其class path中試圖加載該class,如果有,則將該class放入cache中,并返回。如果沒(méi)有,接下一步。

          6. 由application的classloader在其class path中試圖加載該class,如果有,則將該class放入cache中,并返回。如果沒(méi)有,則拋出ClassNotFound的exception。



          Java虛擬機(jī)加載這些java對(duì)象:

          每個(gè)java虛擬機(jī)都在其啟動(dòng)時(shí)產(chǎn)生一個(gè)唯一的class heap,并把所有的class instance都分配在其中。其中每個(gè)類(lèi)實(shí)例的信息又分兩部分,fields域和methods域。每個(gè)類(lèi)實(shí)例各自擁有fields,但同一個(gè)類(lèi)的不同實(shí)例共享methods



          反射

          JVM對(duì)反射的處理

          簡(jiǎn)單例子代碼:

          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.

          }

          }

          }


          復(fù)雜例子代碼:

          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虛擬機(jī)把每個(gè)methods當(dāng)作一個(gè)執(zhí)行單元。該執(zhí)行單元帶有兩種簽名:類(lèi)簽名和屬性簽名(public,static等)。 反射的第一步,驗(yàn)證簽名的合法性。驗(yàn)證通過(guò)后,順序執(zhí)行該method中的指令,當(dāng)需要訪問(wèn)類(lèi)實(shí)例的fields和傳入?yún)?shù)時(shí),由虛擬機(jī)注入。



          動(dòng)態(tài)代理

          Sun對(duì)動(dòng)態(tài)代理的說(shuō)明:

          一個(gè)簡(jiǎn)單例子代碼:

          動(dòng)態(tài)代理的內(nèi)部實(shí)現(xiàn)——代碼生成:

          研究JDK源代碼,發(fā)現(xiàn)在Proxy的sun實(shí)現(xiàn)中調(diào)用了sun.misc.ProxyGenerator類(lèi)的generateProxyClass( proxyName, interfaces)方法,其返回值為byte[]和class文件的內(nèi)存類(lèi)型一致。于是做如下試驗(yàn):

          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.

          }

          }

          }


          運(yùn)行該類(lèi),到class文件夾下,利用反編譯技術(shù),發(fā)現(xiàn)原來(lái)其采用了代碼生產(chǎn)技術(shù):



          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());

          }

          }


          posted on 2007-12-17 16:19 xyz 閱讀(296) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): 網(wǎng)絡(luò)文摘

          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          留言簿

          隨筆檔案(1)

          文章分類(lèi)(44)

          文章檔案(46)

          收藏夾(1)

          Adobe

          AOP

          API

          appServer

          BI

          c

          • c-free
          • codeblocks
          • codelite
          • CodeLite IDE 是一個(gè)強(qiáng)大的開(kāi)源,跨平臺(tái)的 C/C++整合開(kāi)發(fā)環(huán)境. 支持包括 Windows、Linux 和 Mac 系統(tǒng)下運(yùn)行
          • codelite官網(wǎng)
          • dev-c++
          • Dev-C++是一個(gè)C&C++開(kāi)發(fā)工具,它是一款自由軟件,遵守GPL協(xié)議。
          • GCC
          • GCC 原名為 GNU C 語(yǔ)言編譯器(GNU C Compiler),因?yàn)樗局荒芴幚?C語(yǔ)言。GCC 很快地?cái)U(kuò)展,變得可處理 C++。之后也變得可處理 Fortran、Pascal、Objective-C、Java, 以及 Ada 與其他語(yǔ)言。

          Cache

          CMS

          DB

          eclipse

          FreeMarker

          hibernate

          html5

          ibatis

          java

          jquery

          js

          json

          Linux

          Log

          mail server

          mobile

          mysql

          oauth

          openID

          other

          PHP

          portal

          report

          Scheduler

          schema

          Security

          SOA

          spring

          struts

          UI原型設(shè)計(jì)

          w3c

          Wap

          webservice

          xml

          供應(yīng)鏈管理

          博客鏈接

          好網(wǎng)站

          工作流

          開(kāi)源網(wǎng)

          招聘

          插件下載

          操作系統(tǒng)

          構(gòu)建可伸縮的系統(tǒng)

          構(gòu)建工具

          測(cè)試

          • IETest
          • IE官網(wǎng)
          • OpenSTA
          • Siege
          • Siege是一個(gè)壓力測(cè)試和評(píng)測(cè)工具,設(shè)計(jì)用于WEB開(kāi)發(fā)這評(píng)估應(yīng)用在壓力下的承受能力

          游戲

          源碼托管

          經(jīng)營(yíng)

          資源

          金融/財(cái)務(wù)

          搜索

          •  

          最新評(píng)論

          主站蜘蛛池模板: 普兰县| 龙江县| 甘洛县| 涟源市| 石阡县| 托克托县| 琼结县| 额尔古纳市| 水富县| 庆阳市| 响水县| 蚌埠市| 东兰县| 临夏县| 巫溪县| 琼中| 资中县| 辰溪县| 尼木县| 泾川县| 湖南省| 岳西县| 平遥县| 宝兴县| 呼玛县| 苍梧县| 应用必备| 廉江市| 买车| 庆元县| 饶平县| 临漳县| 虹口区| 临湘市| 白玉县| 西安市| 阿克陶县| 黔西| 武邑县| 哈尔滨市| 南雄市|