java动态加载

Posted GZ.Jackey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java动态加载相关的知识,希望对你有一定的参考价值。

先贴个笔记,后续用得着再深究。

 

package test;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class SimpleRun {

    public static void showCompile() {
        // Prepare source somehow.
        String source = "package test; public class Test { static { System.out.println(\"hello\"); } public Test() { System.out.println(\"world\");} public void Hello(){System.out.println(\"fuck\");} }";
        // Save source in .java file.
        File root = new File("~/temp"); // On Windows running on C:\, this is
                                        // C:\java.
        File sourceFile = new File(root, "test/Test.java");
        sourceFile.getParentFile().mkdirs();
        try {
            Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
            // Compile source file.
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            int success = compiler.run(null, null, null, sourceFile.getPath());
            if (success == 0) {
                // Load and instantiate compiled class.
                URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
                Class<?> cls;
                try {
                    // Should print "hello".
                    cls = Class.forName("test.Test", true, classLoader);
                    // Should print "world".
                    Object instance = cls.newInstance();
                    // Should print "[email protected]".
                    System.out.println(instance);
                    Method m = cls.getMethod("Hello", new Class<?>[] {});
                    System.out.println(m);
                    m.invoke(instance, new Object[]{});
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("compile failed");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static double calculate(String expr) {
        String className = "Calculator";
        String methodName = "calculate";
        String source = "package test;  public class " + className + " { public static double " + methodName + "() { return " + expr
                + "; } }";
        // set work directory
        File root = new File("~/temp");
        // set work package
        File sourceFile = new File(root, "test/Calculator.java");
        sourceFile.getParentFile().mkdirs();
        try {
            Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
            // Compile source file.
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            int success = compiler.run(null, null, null, sourceFile.getPath());
            if (success == 0) {
                // Load and instantiate compiled class.
                URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
                Class<?> cls;
                try {
                    cls = Class.forName("test.Calculator", true, classLoader);
                    Object instance = cls.newInstance();
                    Method method = cls.getMethod(methodName, new Class<?>[] {});
                    Object value = method.invoke(instance, new Object[] {});
                    return (Double) value;
                } catch (ClassNotFoundException | IllegalAccessException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("compile failed");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0.0;
    }

    public static void main(String[] args) {
        SimpleRun.showCompile();
        if (args.length >= 1) {
            System.out.println(args[0] + "=" + SimpleRun.calculate(args[0]));
        }
    }
}

 

参考:

http://www.infoq.com/cn/articles/cf-java-byte-code

以上是关于java动态加载的主要内容,如果未能解决你的问题,请参考以下文章

java 动态片段实例化

element Cascader 级联选择器动态加载实例

java 的ViewPage +片段懒加载

JAVA之AOP

Android ViewPager + 带有动态 ListViews 的片段

动态 Rstudio 代码片段