最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)的自定義類加載器示例

 更新時(shí)間:2019年07月17日 08:48:51   作者:cakincqm  
這篇文章主要介紹了Java實(shí)現(xiàn)的自定義類加載器,結(jié)合具體實(shí)例形式分析了java自定義類加載器的原理與具體實(shí)現(xiàn)技巧,需要的朋友可以參考下

本文實(shí)例講述了Java實(shí)現(xiàn)的自定義類加載器。分享給大家供大家參考,具體如下:

一 點(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 自定義加載器
CompileClassLoader:正在編譯 Hello.java...
運(yùn)行Hello的參數(shù):自定義加載器

更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O(shè)計(jì)入門與進(jìn)階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • java實(shí)現(xiàn)分頁顯示效果

    java實(shí)現(xiàn)分頁顯示效果

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)頁顯示效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Java設(shè)計(jì)模式之代理模式與@Async異步注解失效的解決

    Java設(shè)計(jì)模式之代理模式與@Async異步注解失效的解決

    代理模式是Java常見的設(shè)計(jì)模式之一。所謂代理模式是指客戶端并不直接調(diào)用實(shí)際的對(duì)象,而是通過調(diào)用代理,來間接的調(diào)用實(shí)際的對(duì)象
    2022-07-07
  • EasyExcel自定義下拉注解的三種實(shí)現(xiàn)方式總結(jié)

    EasyExcel自定義下拉注解的三種實(shí)現(xiàn)方式總結(jié)

    使用EasyExcel設(shè)置下拉數(shù)據(jù)時(shí),每次都要?jiǎng)?chuàng)建一個(gè)SheetWriteHandler組件確實(shí)比較繁瑣,為了優(yōu)化這個(gè)過程,我們可以通過自定義注解來簡(jiǎn)化操作,下面就來看看具體實(shí)現(xiàn)方法吧
    2024-10-10
  • Java遞歸實(shí)現(xiàn)迷宮游戲

    Java遞歸實(shí)現(xiàn)迷宮游戲

    這篇文章主要介紹了如何利用Java遞歸方法實(shí)現(xiàn)迷宮游戲,下面文章會(huì)詳細(xì)的從為問題描述開始,清晰的解題思路以及詳細(xì)的代碼實(shí)現(xiàn),具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2021-12-12
  • 詳解SpringBoot中使用RabbitMQ的RPC功能

    詳解SpringBoot中使用RabbitMQ的RPC功能

    這篇文章主要介紹了詳解SpringBoot中使用RabbitMQ的RPC功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • Spring干預(yù)Bean的生命周期的方法詳解

    Spring干預(yù)Bean的生命周期的方法詳解

    Spring 提供了多種機(jī)制讓我們能夠在 Bean 生命周期的不同節(jié)點(diǎn)“插入”自己的邏輯,這些機(jī)制可以分為兩大類:針對(duì)單個(gè) Bean 的干預(yù)和針對(duì)所有/多個(gè) Bean 的全局干預(yù),本文將通過代碼示例給大家詳細(xì)的介紹一下,需要的朋友可以參考下
    2025-07-07
  • Spring?AOP通知類型與實(shí)戰(zhàn)示例講解

    Spring?AOP通知類型與實(shí)戰(zhàn)示例講解

    Spring?AOP提供了五種通知類型:@Before、@After、@AfterReturning、@AfterThrowing和@Around,每種通知類型都有其特定的使用場(chǎng)景和實(shí)現(xiàn)方式,通過合理使用這些通知類型,可以實(shí)現(xiàn)各種橫切關(guān)注點(diǎn)的模塊化和解耦,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • SpringBoot集成免費(fèi)的EdgeTTS實(shí)現(xiàn)文本轉(zhuǎn)語音

    SpringBoot集成免費(fèi)的EdgeTTS實(shí)現(xiàn)文本轉(zhuǎn)語音

    在需要文本轉(zhuǎn)語音(TTS)的應(yīng)用場(chǎng)景中(如語音助手、語音通知、內(nèi)容播報(bào)等),Java生態(tài)缺少類似Python生態(tài)的Edge?TTS?客戶端庫,不過沒關(guān)系,現(xiàn)在可以通過?UnifiedTTS?提供的?API?來調(diào)用免費(fèi)的?EdgeTTS?能力,本文給大家介紹了SpringBoot集成免費(fèi)的EdgeTTS實(shí)現(xiàn)文本轉(zhuǎn)語音
    2025-10-10
  • java后臺(tái)防止表單重復(fù)提交方法詳解

    java后臺(tái)防止表單重復(fù)提交方法詳解

    這篇文章主要介紹了后臺(tái)防止表單重復(fù)提交,利用Session防止表單重復(fù)提交,判斷請(qǐng)求url和數(shù)據(jù)是否和上一次相同,利用Spring AOP和redis的鎖需要的朋友可以參考下
    2022-12-12
  • Java8 List集合如何移除滿足條件的元素

    Java8 List集合如何移除滿足條件的元素

    這篇文章主要介紹了Java8 List集合如何移除滿足條件的元素,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11

最新評(píng)論

宕昌县| 山丹县| 延吉市| 镇原县| 镶黄旗| 景东| 内丘县| 融水| 新乡市| 莱芜市| 丘北县| 古丈县| 邹城市| 钟祥市| 平罗县| 钟祥市| 新宁县| 东乌珠穆沁旗| 应城市| 灵川县| 通海县| 巴彦淖尔市| 彭阳县| 库车县| 天门市| 嘉禾县| 永城市| 高邮市| 武定县| 墨玉县| 镇远县| 科尔| 清原| 平谷区| 哈尔滨市| 宁南县| 隆林| 兴海县| 元阳县| 无为县| 弥勒县|