java动态创建class-两种方式(写入文件和非文件

首先是写入文件方式:
两个文件的目录结构(忽略其他的文件,哈哈哈)

Test.java在org.myself.pojo包下,生成的class文件在target/class下(重点:1.编译class 2.加载class文件)

    private static void createStudentByFile() throws Exception{
        String studentString = "package org.myself.pojo;public class Test{private String studentId;public String getStudentId(){return this.studentId;}public void setStudentId(String studentId){this.studentId = studentId;}}";
        String fileName = System.getProperty("user.dir") + "/src/main/java/org/myself/pojo/Test.java";
        File file = new File(fileName);
        FileWriter fileWriter = new FileWriter(file);
        fileWriter.write(studentString);
        fileWriter.flush();
        fileWriter.close();
 
 
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager manager = compiler.getStandardFileManager(null,null,null);
        Iterable<? extends JavaFileObject> javaFileObjects = manager.getJavaFileObjects(fileName);
        String dest = System.getProperty("user.dir") + "/target/classes";
 
        //options就是指定编译输入目录,与我们命令行写javac -d C://是一样的
 
        List<String> options = new ArrayList<String>();
        options.add("-d");
        options.add(dest);
        JavaCompiler.CompilationTask task = compiler.getTask(null,manager,null,options,null,javaFileObjects);
        task.call();
        manager.close();
        URL[] urls = new URL[]{new URL("file:/" + System.getProperty("user.dir") + "/target/classes")};
 
        //加载class时要告诉你的classloader去哪个位置加载class文件
 
        ClassLoader classLoader = new URLClassLoader(urls);
        Object student = classLoader.loadClass("org.myself.pojo.Test").newInstance();
        logger.info("student===={}",student);
 
    }
不写入文件,直接从内存中创建class
    public static void main(String[] args) {
        try {
            Object student = createStudent();
            Method setStudentIdMethod = student.getClass().getMethod("setStudentId", Integer.class);
            Method getStudentIdMethod = student.getClass().getMethod("getStudentId");
            if (setStudentIdMethod != null) {
                setStudentIdMethod.invoke(student, new Integer(1101));
                Object studentId = getStudentIdMethod.invoke(student);
                logger.info("设置的studentId为:{}", studentId.toString());
            }
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
 
    private static String classString = "/* hehha */" +
            "public class Student{                                  " +
            "       private Integer  studentId;                      " +
            "       public Integer getStudentId(){                   " +
            "           return this.studentId;                      " +
            "       }                                               " +
            "       public void setStudentId(Integer studentId){  " +
            "           this.studentId = studentId;                 " +
            "       }                                               " +
            "}                                                    ";
 
    private static Object createStudent() throws URISyntaxException, ClassNotFoundException, IllegalAccessException, InstantiationException, IOException, NoSuchMethodException, InvocationTargetException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);
        ClassJavaFileManager classJavaFileManager = new ClassJavaFileManager(standardFileManager);
        StringObject stringObject = new StringObject(new URI("Student.java"), JavaFileObject.Kind.SOURCE, classString);
        JavaCompiler.CompilationTask task = compiler.getTask(null, classJavaFileManager, null, null, null, Arrays.asList(stringObject));
        if (task.call()) {
            ClassJavaFileObject javaFileObject = classJavaFileManager.getClassJavaFileObject();
            ClassLoader classLoader = new MyClassLoader(javaFileObject);
            Object student = classLoader.loadClass("Student").newInstance();
            return student;
//            Method getStudetnId = student.getClass().getMethod("getStudentId");
//            Object invoke = getStudetnId.invoke(student);
//            logger.info("class==={}", student);
        }
        return null;
    }
    /**
    *自定义fileManager
    */
    static class ClassJavaFileManager extends ForwardingJavaFileManager{
 
        private ClassJavaFileObject classJavaFileObject;
        public ClassJavaFileManager(JavaFileManager fileManager) {
            super(fileManager);
        }
 
        public ClassJavaFileObject getClassJavaFileObject() {
            return classJavaFileObject;
        }
        //这个方法一定要自定义
        @Override
        public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
            return (classJavaFileObject = new ClassJavaFileObject(className,kind));
        }
    }
    /**
     * 存储源文件
     */
    static class StringObject extends SimpleJavaFileObject{
 
        private String content;
 
        public StringObject(URI uri, Kind kind, String content) {
            super(uri, kind);
            this.content = content;
        }
 
        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
            return this.content;
        }
    }
 
    /**
     * class文件(不需要存到文件中)
     */
    static class ClassJavaFileObject extends SimpleJavaFileObject{
 
        ByteArrayOutputStream outputStream;
 
        public ClassJavaFileObject(String className, Kind kind) {
            super(URI.create(className + kind.extension), kind);
            this.outputStream = new ByteArrayOutputStream();
        }
        //这个也要实现
        @Override
        public OutputStream openOutputStream() throws IOException {
            return this.outputStream;
        }
 
        public byte[] getBytes(){
            return this.outputStream.toByteArray();
        }
    }
    //自定义classloader
    static class MyClassLoader extends ClassLoader{
        private ClassJavaFileObject stringObject;
        public MyClassLoader(ClassJavaFileObject stringObject){
            this.stringObject = stringObject;
        }
 
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            byte[] bytes = this.stringObject.getBytes();
            return defineClass(name,bytes,0,bytes.length);
        }
    }
 
————————————————
版权声明:本文为CSDN博主「zhao_xinhu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhao_xinhu/article/details/82499062

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值