(從csdn的blog轉(zhuǎn)來)?

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

?

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

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

bootstrap sun.boot.class.path

extension: java.ext.dirs

application: java.class.path

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

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

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

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

3.?????? 首先查看 bootstrap classloader 中是否已有對應(yīng)的 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 虛擬機(jī)加載這些 java 對象:

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

?

反射

JVM 對反射的處理

簡單例子代碼:

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

?

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

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

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

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

研究 JDK 源代碼,發(fā)現(xiàn)在 Proxy sun 實(shí)現(xiàn)中調(diào)用了 sun.misc.ProxyGenerator 類的 generateProxyClass( proxyName, interfaces) 方法,其返回值為 byte[] class 文件的內(nè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)行該類,到 class 文件夾下,利用反編譯技術(shù),發(fā)現(xiàn)原來其采用了代碼生產(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());

??????? }

??? }

}

?

?