Java中怎么自定義一個(gè)類加載器

Java中怎么自定義一個(gè)類加載器,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

鷹潭ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!

一 點(diǎn)睛

1 ClassLoader類有如下兩個(gè)關(guān)鍵方法:

loadClass(String name, boolean resolve):該方法為ClassLoader的入口點(diǎn),根據(jù)指定的二進(jìn)制名稱來加載類,系統(tǒng)就是調(diào)用ClassLoader的該方法來獲取指定類對(duì)應(yīng)的Class對(duì)象。

findClass(String name):根據(jù)二進(jìn)制名稱來查找類。

如果需要實(shí)現(xiàn)自定義的ClassLoader,可以通過重寫以上兩個(gè)方法來實(shí)現(xiàn),當(dāng)然我們推薦重寫findClass()方法,而不是重寫loadClass()方法。

2 自定義類加載器常用功能

執(zhí)行代碼前自動(dòng)驗(yàn)證數(shù)字簽名。

根據(jù)用戶提供的密碼解密代碼,從而可以實(shí)現(xiàn)代碼混淆器來避免反編譯class文件。

根據(jù)用戶需求來動(dòng)態(tài)地加載類。

根據(jù)應(yīng)用需求把其他數(shù)據(jù)以字節(jié)碼的形式加載到應(yīng)用中。

二 實(shí)戰(zhàn)

1 CompileClassLoader.java

import java.io.*;import java.lang.reflect.*;public class CompileClassLoader extends ClassLoader{  // 讀取一個(gè)文件的內(nèi)容  private byte[] getBytes(String filename)     throws IOException  {   File file = new File(filename);   long len = file.length();   byte[] raw = new byte[(int)len];   try(      FileInputStream fin = new FileInputStream(file))   {     // 一次讀取class文件的全部二進(jìn)制數(shù)據(jù)     int r = fin.read(raw);     if(r != len)      throw new IOException("無法讀取全部文件:"         + r + " != " + len);     return raw;   }  }  // 定義編譯指定Java文件的方法  private boolean compile(String javaFile)     throws IOException  {   System.out.println("CompileClassLoader:正在編譯 "      + javaFile + "...");   // 調(diào)用系統(tǒng)的javac命令   Process p = Runtime.getRuntime().exec("javac " + javaFile);   try   {     // 其他線程都等待這個(gè)線程完成     p.waitFor();   }   catch(InterruptedException ie)   {     System.out.println(ie);   }   // 獲取javac線程的退出值   int ret = p.exitValue();   // 返回編譯是否成功   return ret == 0;  }  // 重寫ClassLoader的findClass方法  protected Class<?> findClass(String name)     throws ClassNotFoundException  {   Class clazz = null;   // 將包路徑中的點(diǎn)(.)替換成斜線(/)。   String fileStub = name.replace("." , "/");   String javaFilename = fileStub + ".java";   String classFilename = fileStub + ".class";   File javaFile = new File(javaFilename);   File classFile = new File(classFilename);   // 當(dāng)指定Java源文件存在,且class文件不存在、或者Java源文件   // 的修改時(shí)間比class文件修改時(shí)間更晚,重新編譯   if(javaFile.exists() && (!classFile.exists()      || javaFile.lastModified() > classFile.lastModified()))   {     try     {      // 如果編譯失敗,或者該Class文件不存在      if(!compile(javaFilename) || !classFile.exists())      {        throw new ClassNotFoundException(           "ClassNotFoundExcetpion:" + javaFilename);      }     }     catch (IOException ex)     {      ex.printStackTrace();     }   }   // 如果class文件存在,系統(tǒng)負(fù)責(zé)將該文件轉(zhuǎn)換成Class對(duì)象   if (classFile.exists())   {     try     {      // 將class文件的二進(jìn)制數(shù)據(jù)讀入數(shù)組      byte[] raw = getBytes(classFilename);      // 調(diào)用ClassLoader的defineClass方法將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成Class對(duì)象      clazz = defineClass(name,raw,0,raw.length);     }     catch(IOException ie)     {      ie.printStackTrace();     }   }   // 如果clazz為null,表明加載失敗,則拋出異常   if(clazz == null)   {     throw new ClassNotFoundException(name);   }   return clazz;  }  // 定義一個(gè)主方法  public static void main(String[] args) throws Exception  {   // 如果運(yùn)行該程序時(shí)沒有參數(shù),即沒有目標(biāo)類   if (args.length < 1)   {     System.out.println("缺少目標(biāo)類,請(qǐng)按如下格式運(yùn)行Java源文件:");     System.out.println("java CompileClassLoader ClassName");   }   // 第一個(gè)參數(shù)是需要運(yùn)行的類   String progClass = args[0];   // 剩下的參數(shù)將作為運(yùn)行目標(biāo)類時(shí)的參數(shù),   // 將這些參數(shù)復(fù)制到一個(gè)新數(shù)組中   String[] progArgs = new String[args.length-1];   System.arraycopy(args , 1 , progArgs      , 0 , progArgs.length);   CompileClassLoader ccl = new CompileClassLoader();   // 加載需要運(yùn)行的類   Class<?> clazz = ccl.loadClass(progClass);   // 獲取需要運(yùn)行的類的主方法   Method main = clazz.getMethod("main" , (new String[0]).getClass());   Object[] argsArray = {progArgs};   main.invoke(null,argsArray);  }}

2 Hello.java

public class Hello{  public static void main(String[] args)  {   for (String arg : args)   {     System.out.println("運(yùn)行Hello的參數(shù):" + arg);   }  }}

3 運(yùn)行

E:\Java\瘋狂java講義\codes\18\18.2>java CompileClassLoader Hello 

看完上述內(nèi)容,你們掌握J(rèn)ava中怎么自定義一個(gè)類加載器的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

網(wǎng)站名稱:Java中怎么自定義一個(gè)類加載器
當(dāng)前路徑:http://muchs.cn/article12/ihigdc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、面包屑導(dǎo)航定制開發(fā)、全網(wǎng)營(yíng)銷推廣電子商務(wù)、網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)