Calvin's Tech Space

          成于堅忍,毀于浮躁

             :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理

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

           

          Java 虛擬機查找這些 java 對象:

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

          bootstrap : sun.boot.class.path

          extension: java.ext.dirs

          application: java.class.path

          三個 class path 各有對應的 classloader 。由上而下形成父子關(guān)系

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

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

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

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

          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 虛擬機都在其啟動時產(chǎn)生一個唯一的 class heap ,并把所有的 class instance 都分配在其中。其中每個類實例的信息又分兩部分, fields 域和 methods 域。每個類實例各自擁有 fields ,但同一個類的不同實例共享 methods

           

          反射

          JVM 對反射的處理

          簡單例子代碼:

           1import java.lang.reflect.InvocationHandler; 
           2
           3import java.lang.reflect.Method; 
           4
           5import java.lang.reflect.InvocationTargetException; 
           6
           7import java.io.IOException; 
           8
           9  
          10
          11public class Main 
          12
          13    public static void main(String[] args)
          14
          15        TempImpl t1 = new TempImpl("temp1"); 
          16
          17        try 
          18
          19            Method t1Talk = t1.getClass().getMethod("Talk"new Class[0]) ; 
          20
          21            t1Talk.invoke(t1, null); 
          22
          23        }
           catch (NoSuchMethodException e) 
          24
          25            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates. 
          26
          27        }
           catch (IllegalAccessException e) 
          28
          29            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates. 
          30
          31        }
           catch (InvocationTargetException e) 
          32
          33            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates. 
          34
          35        }
           
          36
          37        try 
          38
          39            System.in.read(); 
          40
          41        }
           catch (IOException e) 
          42
          43            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates. 
          44
          45        }
           
          46
          47    }
           
          48
          49}
           
          50
          51


          復雜例子代碼: 

           1import java.lang.reflect.InvocationHandler; 
           2
           3import java.lang.reflect.Method; 
           4
           5import java.lang.reflect.InvocationTargetException; 
           6
           7import java.io.IOException; 
           8
           9  
          10
          11public class Main 
          12
          13    public static void main(String[] args)
          14
          15        TempImpl t1 = new TempImpl("temp1"); 
          16
          17        TempImpl t2 = new TempImpl("temp2"); 
          18
          19        Temp2 temp2 = new Temp2(); 
          20
          21        try 
          22
          23            Method t1Talk = t1.getClass().getMethod("Talk"new Class[0]) ; 
          24
          25            Method t2Talk = t2.getClass().getMethod("Talk"new Class[0]) ; 
          26
          27            t1Talk.invoke(t2, null); 
          28
          29            t2Talk.invoke(t1, null); 
          30
          31            if(t1Talk.equals(t2Talk))
          32
          33                System.out.println("equals"); 
          34
          35            }
           
          36
          37           else
          38
          39                System.out.println("not equals"); 
          40
          41            }
           
          42
          43            if(t1Talk==t2Talk)
          44
          45                System.out.println("ref equals"); 
          46
          47            }
           
          48
          49           else
          50
          51                System.out.println("ref not equals"); 
          52
          53            }
           
          54
          55            t2Talk.invoke(temp2, null); 
          56
          57        }
           catch (NoSuchMethodException e) 
          58
          59            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates. 
          60
          61        }
           catch (IllegalAccessException e) 
          62
          63            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates. 
          64
          65        }
           catch (InvocationTargetException e) 
          66
          67            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates. 
          68
          69        }
           
          70
          71        try 
          72
          73            System.in.read(); 
          74
          75        }
           catch (IOException e) 
          76
          77            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates. 
          78
          79        }
           
          80
          81    }
           
          82
          83}
           
          84
          85

           

          分析: java 虛擬機把每個 methods 當作一個執(zhí)行單元。該執(zhí)行單元帶有兩種簽名:類簽名和屬性簽名( public , static 等)。 反射的第一步,驗證簽名的合法性。驗證通過后,順序執(zhí)行該 method 中的指令,當需要訪問類實例的 fields 和傳入?yún)?shù)時,由虛擬機注入。

          動態(tài)代理

          Sun 對動態(tài)代理的說明:

          一個簡單例子代碼:

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

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

           1public class  ProxyClassFile
           2
           3       public static void main(String[] args)
           4
           5              String proxyName = "TempProxy"
           6
           7        TempImpl t = new TempImpl("proxy"); 
           8
           9              Class[] interfaces =t.getClass().getInterfaces(); 
          10
          11              
          12
          13              byte[] proxyClassFile = ProxyGenerator.generateProxyClass( 
          14
          15                  proxyName, interfaces); 
          16
          17        File f = new File("classes/TempProxy.class"); 
          18
          19        try 
          20
          21            FileOutputStream fos = new FileOutputStream(f); 
          22
          23            fos.write(proxyClassFile); 
          24
          25            fos.flush(); 
          26
          27            fos.close(); 
          28
          29        }
           catch (FileNotFoundException e) 
          30
          31            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates. 
          32
          33        }
           catch (IOException e) 
          34
          35            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates. 
          36
          37        }
           
          38
          39       }
           
          40}
           
          41
          42


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

           

            1public interface Temp
            2
            3       public void Talk(); 
            4
            5       public void Run(); 
            6
            7}
           
            8
            9import java.lang.reflect.*
           10
           11  
           12
           13public final class TempProxy extends Proxy 
           14
           15    implements Temp
           16
           17  
           18
           19    private static Method m4; 
           20
           21    private static Method m2; 
           22
           23    private static Method m0; 
           24
           25    private static Method m3; 
           26
           27    private static Method m1; 
           28
           29  
           30
           31    public TempProxy(InvocationHandler invocationhandler)   
           32
           33        super(invocationhandler); 
           34
           35    }
           
           36
           37  
           38
           39    public final void Run()    
           40
           41        try 
           42
           43            h.invoke(this, m4, null); 
           44
           45            return
           46
           47        }
           
           48
           49        catch(Error _ex) { } 
           50
           51        catch(Throwable throwable)  
           52
           53            throw new UndeclaredThrowableException(throwable); 
           54
           55        }
           
           56
           57    }
           
           58
           59  
           60
           61    public final String toString()
           62
           63        try
           64
           65            return (String)h.invoke(this, m2, null); 
           66
           67        }
           
           68
           69        catch(Error _ex) { } 
           70
           71        catch(Throwable throwable)  
           72
           73            throw new UndeclaredThrowableException(throwable); 
           74
           75        }
           
           76
           77        return ""
           78
           79    }
           
           80
           81  
           82
           83    public final int hashCode() 
           84
           85        try 
           86
           87            return ((Integer)h.invoke(this, m0, null)).intValue(); 
           88
           89        }
           
           90
           91        catch(Error _ex) { } 
           92
           93        catch(Throwable throwable)
           94
           95            throw new UndeclaredThrowableException(throwable); 
           96
           97        }
           
           98
           99        return 123
          100
          101    }
           
          102
          103  
          104
          105    public final void Talk()
          106
          107        try
          108
          109            h.invoke(this, m3, null); 
          110
          111            return
          112
          113        }
           
          114
          115        catch(Error _ex) { } 
          116
          117        catch(Throwable throwable) 
          118
          119            throw new UndeclaredThrowableException(throwable); 
          120
          121        }
           
          122
          123    }
           
          124
          125  
          126
          127    public final boolean equals(Object obj) 
          128
          129        try  
          130
          131            return ((Boolean)h.invoke(this, m1, new Object[] 
          132
          133                obj 
          134
          135            }
          )).booleanValue(); 
          136
          137        }
           
          138
          139        catch(Error _ex) { } 
          140
          141        catch(Throwable throwable) 
          142
          143            throw new UndeclaredThrowableException(throwable); 
          144
          145        }
           
          146
          147        return false
          148
          149    }
           
          150
          151  
          152
          153    static
          154
          155        try
          156
          157     m4 = Class.forName("Temp").getMethod("Run"new Class[0]); 
          158
          159     m2 = Class.forName("java.lang.Object").getMethod("toString"new Class[0]); 
          160
          161     m0 = Class.forName("java.lang.Object").getMethod("hashCode"new Class[0]); 
          162
          163     m3 = Class.forName("Temp").getMethod("Talk"new Class[0]); 
          164
          165     m1 = Class.forName("java.lang.Object").getMethod("equals"new Class[] 
          166
          167                Class.forName("java.lang.Object"
          168
          169            }
          ); 
          170
          171        }
           
          172
          173        catch(NoSuchMethodException nosuchmethodexception) 
          174
          175            throw new NoSuchMethodError(nosuchmethodexception.getMessage()); 
          176
          177        }
           
          178
          179        catch(ClassNotFoundException classnotfoundexception) 
          180
          181            throw new NoClassDefFoundError(classnotfoundexception.getMessage()); 
          182
          183        }
           
          184
          185    }
           
          186
          187}

          188
          189



          本文地址:
          http://www.aygfsteel.com/AndersLin/archive/2006/06/11/51997.html

          posted on 2009-08-20 16:00 calvin 閱讀(331) 評論(0)  編輯  收藏 所屬分類: Framework

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 伊吾县| 嘉禾县| 英山县| 新乡县| 蒙自县| 岱山县| 肥乡县| 江安县| 扎兰屯市| 武汉市| 疏附县| 灵石县| 余干县| 江永县| 民丰县| 高碑店市| 沙洋县| 玉林市| 余干县| 宁德市| 东乌珠穆沁旗| 金门县| 宣恩县| 逊克县| 沈阳市| 峨山| 辽源市| 盘山县| 天镇县| 邢台市| 九寨沟县| 甘洛县| 荣成市| 棋牌| 惠东县| 莎车县| 溧水县| 荔波县| 贺兰县| 乌拉特后旗| 玉树县|