真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何在Java中自定義一個(gè)類(lèi)加載器示例

本篇文章給大家分享的是有關(guān)如何在Java中自定義一個(gè)類(lèi)加載器示例,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著小編一起來(lái)看看吧。

在呼倫貝爾等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶(hù)提供網(wǎng)站建設(shè)、成都網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需策劃設(shè)計(jì),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣,外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè),呼倫貝爾網(wǎng)站建設(shè)費(fèi)用合理。

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

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

findClass(String name):根據(jù)二進(jìn)制名稱(chēng)來(lái)查找類(lèi)。

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

2 自定義類(lèi)加載器常用功能

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

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

根據(jù)用戶(hù)需求來(lái)動(dòng)態(tài)地加載類(lè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("無(wú)法讀取全部文件:"
         + 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
   {
     // 其他線(xiàn)程都等待這個(gè)線(xiàn)程完成
     p.waitFor();
   }
   catch(InterruptedException ie)
   {
     System.out.println(ie);
   }
   // 獲取javac線(xiàn)程的退出值
   int ret = p.exitValue();
   // 返回編譯是否成功
   return ret == 0;
  }
  // 重寫(xiě)ClassLoader的findClass方法
  protected Class findClass(String name)
     throws ClassNotFoundException
  {
   Class clazz = null;
   // 將包路徑中的點(diǎn)(.)替換成斜線(xià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í)沒(méi)有參數(shù),即沒(méi)有目標(biāo)類(lèi)
   if (args.length < 1)
   {
     System.out.println("缺少目標(biāo)類(lèi),請(qǐng)按如下格式運(yùn)行Java源文件:");
     System.out.println("java CompileClassLoader ClassName");
   }
   // 第一個(gè)參數(shù)是需要運(yùn)行的類(lèi)
   String progClass = args[0];
   // 剩下的參數(shù)將作為運(yùn)行目標(biāo)類(lèi)時(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)行的類(lèi)
   Class clazz = ccl.loadClass(progClass);
   // 獲取需要運(yùn)行的類(lèi)的主方法
   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中自定義一個(gè)類(lèi)加載器示例,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


文章名稱(chēng):如何在Java中自定義一個(gè)類(lèi)加載器示例
本文來(lái)源:http://weahome.cn/article/jsgchj.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部