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.blogjava.net/AndersLin/archive/2006/06/11/51997.html

posted on 2009-08-20 16:00 calvin 阅读(321) 评论(0)  编辑  收藏 所属分类: Framework

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问