Calvin's Tech Space

          成于堅忍,毀于浮躁

             :: 首頁 :: 聯系 :: 聚合  :: 管理

          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 對反射的處理

          簡單例子代碼:

           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 當作一個執行單元。該執行單元帶有兩種簽名:類簽名和屬性簽名( public , static 等)。 反射的第一步,驗證簽名的合法性。驗證通過后,順序執行該 method 中的指令,當需要訪問類實例的 fields 和傳入參數時,由虛擬機注入。

          動態代理

          Sun 對動態代理的說明:

          一個簡單例子代碼:

          動態代理的內部實現——代碼生成:

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

           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 文件夾下,利用反編譯技術,發現原來其采用了代碼生產技術:

           

            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

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


          網站導航:
           
          主站蜘蛛池模板: 静海县| 庆安县| 贵港市| 长宁县| 甘肃省| 万盛区| 长兴县| 东方市| 彩票| 广丰县| 古蔺县| 玛多县| 布尔津县| 顺平县| 滨海县| 成安县| 巍山| 合山市| 会同县| 遂溪县| 肥东县| 山西省| 裕民县| 雅江县| 永顺县| 通道| 竹山县| 原平市| 靖边县| 常熟市| 六盘水市| 逊克县| 岳阳县| 浦北县| 卓尼县| 开鲁县| 顺义区| 丹东市| 长乐市| 台安县| 运城市|