JAVA類動態載入的實現

2021-07-10 20:03:51 字數 1686 閱讀 5539

(結束)

以上所述,想必大家對jvm類載入的原理有了一定的了解,大致也猜到實現的方法了吧。

結合上面說到,要jvm重新載入乙個類,一共有3種辦法:(我加了一種)

1.        重新寫乙個新的路徑,更換包名或類名都是可行的方法。

2.        自己寫乙個類的尋找機制取代systemclassloader中的,再呼叫defineclass方法。

3.        覆蓋loadclass方法,自己實現乙個類載入過程。

顯而易見,第一種方法是我自己新增上去的,而且應該是用得最多得方法,因為在對jvm的類搜尋、載入機制不是很熟悉的前提下,只要做一些簡單的修改就能達到所要的效果。(至少在我的專案中,這是首選,因為不會出錯)

但如果第一種方法能實現,本文就沒有寫的意義了。在乙個7 x 24 的大型系統中(如電信,銀行等),用第一種方法,就凸現出它最大問題,就是**變得無比龐大。因為每乙個類的名字不同導致相同功能的類具有兩個或以上的類檔案存在,對**的開發和維護來說,這是非常嚴重的問題。

好,現在又退回到開始,排除掉第一種方法,如果使用第三種方法,應該是可控性最高的方法,但本人才疏學淺,沒有把握把整個類載入過程摸透,因此還是排除的第三種方法。

剩下只有第二種方法了。在classloader中,defineclass方法是比較好理解的,只要傳入類的位元組流即可,因此,我只要重寫一次類檔案的載入。下面是我的實現**:

public class testclassloader extends classloader catch (exception e) {

return null;

return null;

相信大家已經明白了吧。我在classloader構造時便載入了指定的類檔案,因此,就跳過了在new 新的物件時去查詢cache中該類是否有載入的過程。(註明一下:我的類路徑用了url的方式傳入,目的是為了適應多平台的機制,因為window和linux的路徑命名不一樣)

相信聰明的你一定猜到後面應該怎麼做了吧,沒錯,就是用class.forname構建類:

string name = "test.testblank";

url url = new url("file:/c:/test/classes/test/testblank.class");

classloader cl = new testclassloader(name, url);

class c = class.forname(name, false, cl);

//例項化

object obj = c.newinstance();

testinte***ce i = (testinte***ce) obj;

i.run();

你一定注意到了,為什麼我用了乙個testinte***ce,其實自定義classloader中,不能直接以當前的類去直接強制轉換,因為在jvm中,不同的classloader載入同乙個類,在jvm中是兩個完全不同的類。因此,預設的class檔案都是systemclassloader,所以會丟擲classcastexception。解決方法很簡單,只要該物件實現乙個介面,然後用父類去強制轉換就沒有問題了。

java動態載入類

new建立物件是靜態載入類,在編譯時刻就需要載入所有的可能用到的類。而通過動態載入類可以解決此問題 class office if excel equals args 0 以上 在編譯時就會報錯,因為找不到word類和excel類以及其各自的 start 方法.若存在乙個word類,我們編譯器還是不...

Java實現動態載入讀取properties檔案

問題 當我們使用如下語句載入.properties時 classloader classloader this.getclass getclassloader properties prop new properties 會發現修改了.properties後,即使重新執行,讀入的仍為修改前的引數。此...

java動態載入

package com.service import com.xx.domaim public inte ce userserviceps com xx.domain是引用的另乙個工程c的domain 此時如果只是載入了b工程的jar 載入b工程的源 public class classloader...