自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JDK 6動(dòng)態(tài)編譯—內(nèi)存字符串編譯方式

開發(fā) 后端
JDK6開始提供了動(dòng)態(tài)編譯的API,在許多應(yīng)用場景都可以用得著,如動(dòng)態(tài)加載(修改)服務(wù)、高性動(dòng)態(tài)業(yè)務(wù)邏輯實(shí)現(xiàn)(用腳本或模板引擎實(shí)現(xiàn)效率滿足不了需求)等都非常好用。

 

JDK6開始提供了動(dòng)態(tài)編譯的API,在許多應(yīng)用場景都可以用得著,如動(dòng)態(tài)加載(修改)服務(wù)、高性動(dòng)態(tài)業(yè)務(wù)邏輯實(shí)現(xiàn)(用腳本或模板引擎實(shí)現(xiàn)效率滿足不了需求)等都非常好用。

    API對應(yīng)的接口都在javax.tools包下面,常用編譯方式有基于文本文件、內(nèi)存字符串等,實(shí)際上基于URI的字節(jié)流都可以,也就是遠(yuǎn)程Java源代碼也可以。對于常用的已有文件形式的動(dòng)態(tài)編譯網(wǎng)上的實(shí)例已經(jīng)非常多,我在這里介紹下動(dòng)態(tài)編譯內(nèi)存中以字符串的形式。

簡單的代碼流程如下:

Java代碼
  1. //通過系統(tǒng)工具提供者獲得動(dòng)態(tài)編譯器     
  2. JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();     
  3. //獲得一個(gè)文件管理器,它的功能主要是提供所有文件操作的規(guī)則,     
  4. //如源代碼路徑、編譯的classpath,class文件目標(biāo)目錄等,其相關(guān)屬性都提供默認(rèn)值     
  5. StandardJavaFileManager fileManager = compiler.getStandardFileManager(nullnullnull);     
  6.     
  7. //獲得CompilationTask并調(diào)用     
  8. //獲得CompilationTask方法原型:     
  9. getTask(Writer out,     
  10.      JavaFileManager fileManager,     
  11.      DiagnosticListenersuper JavaFileObject> diagnosticListener,     
  12.      Iterable options,     
  13.      Iterable classes,     
  14.      Iterableextends JavaFileObject> compilationUnits)     
  15.     
  16.     
  17. //簡單調(diào)用例子     
  18. boolean b = jc.getTask(null, fileManager, nullnullnull, compilationUnits).call();  

    我這里介紹的字符串形式的編譯(其它方式也會(huì)有相似的具體實(shí)現(xiàn)),還需要提供一個(gè)FileObject一個(gè)實(shí)現(xiàn)類,將相應(yīng)的對象封裝作為getTask()的最后一個(gè)參數(shù)來構(gòu)建具體的編譯Task.

JavaDoc提供的一個(gè)FileObject參考實(shí)現(xiàn):

Class JavaSourceFromString

Java代碼
  1. import java.net.URI;     
  2.     
  3. import javax.tools.SimpleJavaFileObject;     
  4.     
  5. public class JavaSourceFromString extends SimpleJavaFileObject {     
  6.     
  7.     /**    
  8.      *  源碼    
  9.      */    
  10.     final String code;     
  11.     
  12.     /**    
  13.      * 構(gòu)造方法:從字符串中構(gòu)造一個(gè)FileObject    
  14.      * @param name the name of the compilation unit represented by this file object    
  15.      * @param code the source code for the compilation unit represented by this file object    
  16.      */    
  17.     JavaSourceFromString(String name, String code) {     
  18.         super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),     
  19.               Kind.SOURCE);     
  20.         this.code = code;     
  21.     }     
  22.     
  23.     @Override    
  24.     public CharSequence getCharContent(boolean ignoreEncodingErrors) {     
  25.         return code;     
  26.     }     
  27. }    



完整的測試類:
Class TestDyCompile

Java代碼
  1. import java.io.File;     
  2. import java.io.IOException;     
  3. import java.util.Arrays;     
  4.     
  5. import javax.tools.JavaCompiler;     
  6. import javax.tools.JavaFileManager.Location;     
  7. import javax.tools.JavaFileObject;     
  8. import javax.tools.StandardJavaFileManager;     
  9. import javax.tools.StandardLocation;     
  10. import javax.tools.ToolProvider;     
  11.     
  12. import dyclass.Test;     
  13.     
  14.     
  15. public class TestDyCompile {     
  16.     
  17.     /**    
  18.      *     
  19.      * @author ZhangXiang    
  20.      * @param args    
  21.      * 2011-4-7    
  22.      */    
  23.     public static void main(String[] args) {     
  24.              
  25.         StringBuilder classStr = new StringBuilder("package dyclass;public class Foo implements Test{");     
  26.         classStr.append("public void test(){");     
  27.         classStr.append("System.out.println(\"Foo2\");}}");     
  28.              
  29.         JavaCompiler jc = ToolProvider.getSystemJavaCompiler();     
  30.         StandardJavaFileManager fileManager = jc.getStandardFileManager(nullnullnull);     
  31.         Location location = StandardLocation.CLASS_OUTPUT;     
  32.         File[] outputs = new File[]{new File("bin/")};     
  33.         try {     
  34.             fileManager.setLocation(location, Arrays.asList(outputs));     
  35.         } catch (IOException e) {     
  36.             e.printStackTrace();     
  37.         }     
  38.              
  39.         JavaFileObject jfo = new JavaSourceFromString("dyclass.Foo", classStr.toString());     
  40.         JavaFileObject[] jfos = new JavaFileObject[]{jfo};     
  41.         Iterableextends JavaFileObject> compilationUnits = Arrays.asList(jfos);     
  42.         boolean b = jc.getTask(null, fileManager, nullnullnull, compilationUnits).call();     
  43.         if(b){//如果編譯成功     
  44.             try {     
  45.                 Test t = (Test) Class.forName("dyclass.Foo").newInstance();     
  46.                 t.test();     
  47.             } catch (InstantiationException e) {     
  48.                 e.printStackTrace();     
  49.             } catch (IllegalAccessException e) {     
  50.                 e.printStackTrace();     
  51.             } catch (ClassNotFoundException e) {     
  52.                 e.printStackTrace();     
  53.             }     
  54.         }     
  55.     }     
  56. }   



我在這里的具體業(yè)務(wù)類為dyclass.Foo,也就是我們需要?jiǎng)討B(tài)編譯的類,為了方便寫業(yè)務(wù)的調(diào)用代碼,也可以讓我們的業(yè)務(wù)類實(shí)現(xiàn)一個(gè)接口,然后通過反射獲得具體子類強(qiáng)制轉(zhuǎn)換來調(diào)用。

Test接口:

Java代碼
  1. public interface Test {     
  2.     //業(yè)務(wù)方法簽名     
  3.     void test();     
  4. }   


另外,在代碼中還有這么一段:

Java代碼
  1.   Location location = StandardLocation.CLASS_OUTPUT;     
  2.          File[] outputs = new File[]{new File("bin/")};     
  3. try {     
  4.     fileManager.setLocation(location, Arrays.asList(outputs));     
  5. catch (IOException e) {     
  6.     e.printStackTrace();     
  7. }    

這段代碼的作用相信大家一看到它就想到它的作用了,前面有說過JavaFileManager 的作用,我在這里設(shè)置了CLASS文件的輸出目錄,意圖很簡單,我的工程是在Eclipse運(yùn)行的,項(xiàng)目的目標(biāo)路徑就是項(xiàng)目下的bin目錄,如果不設(shè)置的話,class文件輸出路徑即為默認(rèn)值,也就是直接在項(xiàng)目根路徑下,后面直接調(diào)用就不能完成了。當(dāng)然在其它一些應(yīng)用場景中需要設(shè)置為自己需要的目錄。
同樣的方法可以設(shè)置JavaFileManager 其它的我們需要的文件規(guī)則屬性(可以參照枚舉類型StandardLocation),在這里就不一一介紹了。

 

 

責(zé)任編輯:金賀 來源: ITEYE博客
相關(guān)推薦

2024-04-01 08:41:39

字符串.NET

2022-12-27 09:33:28

2009-07-09 10:05:55

2009-12-17 13:23:25

Ruby eval方法

2024-06-26 08:18:08

ES6模板字符串

2021-09-10 08:18:31

Go語言字符串

2021-09-07 09:23:07

C++字符串算法

2010-02-25 13:58:22

Linux JDK

2009-11-26 13:11:24

PHP字符串

2023-12-11 07:33:05

Go語言字符技巧

2023-10-31 18:57:02

Java字符串

2009-12-01 09:18:50

PHP分割字符串

2010-03-23 11:17:16

Python 動(dòng)態(tài)編譯

2009-08-04 18:10:35

ASP.NET動(dòng)態(tài)編譯

2009-08-27 16:29:18

C#動(dòng)態(tài)編譯

2009-02-26 16:28:43

靜態(tài)編譯動(dòng)態(tài)編譯Java

2020-05-13 12:17:33

RedisC字符C語言

2022-08-29 23:49:41

Python字符串代碼

2009-08-04 18:05:37

動(dòng)態(tài)編譯ASP.NET

2019-03-07 15:43:22

Redis數(shù)據(jù)SDS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號