日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 之动态生成类

發布時間:2024/3/13 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 之动态生成类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

@TOCjava 之動態生成類

最近遇到一個需求,要求屬性字段是可以前端動態編輯,然后要求導入導出的數據列要同步屬性字段。導入導出功能不想自己寫,想要集成好的現成工具。可是他是通過類注解獲取屬性的, 然鵝我的屬性是動態的,不可能提前寫好,這可怎么辦呢。。。!于是就開始研究是不是可以動態創建類文件,于是乎經過一番戰痘,查閱大量網上前備們的文獻資資料,總結測試。。。好像可以也(^-^)V

取之與群眾,傳之與群眾

package test;import javax.tools.JavaCompiler; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Objects;/*** desc:自定義的類加載器,用于實現類的動態加載*/ public class MyClassLoader extends ClassLoader {//回車加換行符public String rt = "\r\n";//生成類的源文件,寫成字符串的形式public String src ="package test;"+"public class HelloWorld {" + rt +" public String name;" + rt +" public static void main(String[] args) {" + rt +" System.out.println(\"Hello world!\");" + rt +" }" + rt +" public String getName() {" + rt +" return this.name; " + rt +" }" + rt +" public void setName(String name) {" + rt +" this.name = name;" + rt +" }" + rt +"}";//類路徑 F:/java/code/j2es/out/production/j2es/private String classPath;//類名 類的全限定包名 不帶后綴 例如com.test.Noticeprivate String className = "test.HelloWorld";//class文件路徑 F:/java/code/j2es/out/production/j2es/test/HelloWorld.classprivate final String classPackageName;//java文件路徑 F:/java/code/j2es/out/production/j2es/test/HelloWorld.javaprivate final String javaPackageName;public MyClassLoader(){classPath = Objects.requireNonNull(MyClassLoader.class.getClassLoader().getResource("")).getPath();//獲取編譯后class文件所在的路徑classPath = !classPath.startsWith("/")?classPath:classPath.substring(1);//獲取出來的前面會有一個/,去掉前面的/System.out.println(classPath);String packageName = classPath + className.replace(".",File.separator);//類名轉換路徑classPackageName = packageName + ".class";javaPackageName = packageName + ".java";}public MyClassLoader(String src,String classPath,String className){this.src = src;this.classPath = classPath;this.className = className;String packageName = classPath + className.replace(".",File.separator);//類名轉換路徑classPackageName = packageName + ".class";javaPackageName = packageName + ".java";}/*** 指定的類的class文件是否存在* @return boolean*/private boolean isClassExist() {return FileUtil.isFileExist(classPackageName);}/*** 指定的類java文件是否存在* @return boolean*/private boolean isJavaExist(){return FileUtil.isFileExist(javaPackageName);}/*** 寫文件*/private void writerFile() throws IOException {File file = new File (javaPackageName);FileWriter fw = new FileWriter (file);fw.write(src);fw.flush();fw.close();}/*** 編譯java類* 使用rt.jar中的javax.tools包提供的編譯器*/private void compiler(){JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();StandardJavaFileManager sjfm = compiler.getStandardFileManager (null, null, null);Iterable<? extends JavaFileObject> units = sjfm.getJavaFileObjects (javaPackageName);JavaCompiler.CompilationTask ct = compiler.getTask (null, sjfm, null, null, null, units);ct.call();}/*** 復寫父類的類加載方法* @param name 類的全限定包名 不帶后綴 例如com.test.Notice 而不要寫成com.test.Notice.java* @return Class*/@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {//加載類的字節碼byte[] classBytes;try {classBytes = Files.readAllBytes(Paths.get(classPackageName));} catch (IOException e) {throw new RuntimeException(e);}Class<?> clazz;//將字節碼交給JVMclazz = defineClass(name,classBytes,0,classBytes.length);if(clazz == null){throw new ClassNotFoundException(name);}return clazz;}/*** 動態編譯一個java源文件并加載編譯生成的class*/public Class<?> dynamicLoadClass() throws ClassNotFoundException, IOException {//1、先將字符串源碼寫入java文件writerFile();//2、將java文件編譯成class文件compiler();//3、把編譯好的的交給JVMClass<?> clazz = findClass(className);//得到類后把java源碼文件刪掉if(isJavaExist()){if(!FileUtil.deleteFile(javaPackageName)){System.out.println("刪除源文件失敗!");}}return clazz;}public static void main (String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {MyClassLoader myClassLoader = new MyClassLoader();Class<?> clazz = myClassLoader.dynamicLoadClass();System.out.println(clazz);// 生成對象Object obj = clazz.newInstance();System.out.println(obj);// 調用main方法Method m = clazz.getMethod("main",String[].class);Object invoke = m.invoke(obj, new Object[] { new String[] {} });System.out.println(invoke);//調用setNameMethod m2 = clazz.getMethod("setName",String.class);Object invoke2 = m2.invoke(obj,"zhangsan");System.out.println(invoke2);//getNameMethod m1 = clazz.getMethod("getName");Object invoke1 = m1.invoke(obj);System.out.println(invoke1);} }

何為傳承

前面的人學會了,就要傳授給后面的人,否則學而不傳矢道也,知識得到傳承才能開花和升華,名族才能強大

本文可以隨意轉載

總結

以上是生活随笔為你收集整理的java 之动态生成类的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。