中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JDK6動態編譯的方法是什么

發布時間:2022-01-10 18:01:43 來源:億速云 閱讀:130 作者:iii 欄目:編程語言

這篇文章主要介紹“JDK6動態編譯的方法是什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“JDK6動態編譯的方法是什么”文章能幫助大家解決問題。

JDK6開始提供了動態編譯的API,在許多應用場景都可以用得著,如動態加載(修改)服務、高性動態業務邏輯實現(用腳本或模板引擎實現效率滿足不了需求)等都非常好用。
API對應的接口都在javax.tools包下面,常用編譯方式有基于文本文件、內存字符串等,實際上基于URI的字節流都可以,也就是遠程Java源代碼也可以。對于常用的已有文件形式的動態編譯網上的實例已經非常多,我在這里介紹下動態編譯內存中以字符串的形式。
簡單的代碼流程如下:

Java代碼

//通過系統工具提供者獲得動態編譯器     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();     //獲得一個文件管理器,它的功能主要是提供所有文件操作的規則,     //如源代碼路徑、編譯的classpath,class文件目標目錄等,其相關屬性都提供默認值     StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);         //獲得CompilationTask并調用     //獲得CompilationTask方法原型:     getTask(Writer out,          JavaFileManager fileManager,          DiagnosticListener<? super JavaFileObject> diagnosticListener,          Iterable options,          Iterable classes,          Iterable<? extends JavaFileObject> compilationUnits)             //簡單調用例子     boolean b = jc.getTask(null, fileManager, null, null, null, compilationUnits).call();


我這里介紹的字符串形式的編譯(其它方式也會有相似的具體實現),還需要提供一個FileObject一個實現類,將相應的對象封裝作為getTask()的最后一個參數來構建具體的編譯Task.
JavaDoc提供的一個FileObject參考實現:
Class JavaSourceFromString

Java代碼

import java.net.URI;         import javax.tools.SimpleJavaFileObject;         public class JavaSourceFromString extends SimpleJavaFileObject {             /**         *  源碼         */        final String code;             /**         * 構造方法:從字符串中構造一個FileObject         * @param name the name of the compilation unit represented by this file object         * @param code the source code for the compilation unit represented by this file object         */        JavaSourceFromString(String name, String code) {             super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),                   Kind.SOURCE);             this.code = code;         }             @Override        public CharSequence getCharContent(boolean ignoreEncodingErrors) {             return code;         }     }
 


完整的測試類:
Class TestDyCompile

Java代碼

import java.io.File;     import java.io.IOException;     import java.util.Arrays;         import javax.tools.JavaCompiler;     import javax.tools.JavaFileManager.Location;     import javax.tools.JavaFileObject;     import javax.tools.StandardJavaFileManager;     import javax.tools.StandardLocation;     import javax.tools.ToolProvider;         import dyclass.Test;             public class TestDyCompile {             /**         *          * @author ZhangXiang         * @param args         * 2011-4-7         */        public static void main(String[] args) {                          StringBuilder classStr = new StringBuilder("package dyclass;public class Foo implements Test{");             classStr.append("public void test(){");             classStr.append("System.out.println(\"Foo2\");}}");                          JavaCompiler jc = ToolProvider.getSystemJavaCompiler();             StandardJavaFileManager fileManager = jc.getStandardFileManager(null, null, null);             Location location = StandardLocation.CLASS_OUTPUT;             File[] outputs = new File[]{new File("bin/")};             try {                 fileManager.setLocation(location, Arrays.asList(outputs));             } catch (IOException e) {                 e.printStackTrace();             }                          JavaFileObject jfo = new JavaSourceFromString("dyclass.Foo", classStr.toString());             JavaFileObject[] jfos = new JavaFileObject[]{jfo};             Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(jfos);             boolean b = jc.getTask(null, fileManager, null, null, null, compilationUnits).call();             if(b){//如果編譯成功                 try {                     Test t = (Test) Class.forName("dyclass.Foo").newInstance();                     t.test();                 } catch (InstantiationException e) {                     e.printStackTrace();                 } catch (IllegalAccessException e) {                     e.printStackTrace();                 } catch (ClassNotFoundException e) {                     e.printStackTrace();                 }             }         }     }


我在這里的具體業務類為dyclass.Foo,也就是我們需要動態編譯的類,為了方便寫業務的調用代碼,也可以讓我們的業務類實現一個接口,然后通過反射獲得具體子類強制轉換來調用。
Test接口:

Java代碼

public interface Test {         //業務方法簽名         void test();     }


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

Java代碼

  Location location = StandardLocation.CLASS_OUTPUT;              File[] outputs = new File[]{new File("bin/")};     try {         fileManager.setLocation(location, Arrays.asList(outputs));     } catch (IOException e) {         e.printStackTrace();     }

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

關于“JDK6動態編譯的方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

jdk
AI

伊宁县| 古田县| 南陵县| 楚雄市| 西乌| 寿阳县| 开鲁县| 大宁县| 凤山市| 富民县| 常山县| 靖边县| 五莲县| 金塔县| 桂东县| 南开区| 兴宁市| 巩留县| 抚顺市| 井冈山市| 金平| 化德县| 宁海县| 广德县| 大悟县| 宜昌市| 凤山县| 吉首市| 海南省| 巢湖市| 鄂伦春自治旗| 成都市| 遂平县| 缙云县| 绍兴县| 陵川县| 西安市| 镇平县| 开原市| 开远市| 亳州市|