• Java——动态创建Class(不写入文件,直接从内存中创建class)


    原文:https://blog.csdn.net/zhao_xinhu/article/details/82499062#commentsedit

    参考:https://www.cnblogs.com/xinruyi/p/9413007.html

    package com.java.test.dynamicpojo;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.lang.reflect.Method;
    import java.net.URI;
    import java.util.Arrays;
    
    import javax.tools.FileObject;
    import javax.tools.ForwardingJavaFileManager;
    import javax.tools.JavaCompiler;
    import javax.tools.JavaFileManager;
    import javax.tools.JavaFileObject;
    import javax.tools.SimpleJavaFileObject;
    import javax.tools.StandardJavaFileManager;
    import javax.tools.ToolProvider;
    
    public class DynamicPOJO {
            private static String classString = "public class Student{        "
                    + "       private String  studentId;                      "
                    + "       public String getStudentId(){                   "
                    + "           return studentId;                           "
                    + "       }                                               "
                    + "       public void setStudentId(String studentId){     "
                    + "           this.studentId = studentId;                 "
                    + "       }                                               "
                    + "}                                                      ";
    
            private static void createStudent() throws Exception {
                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();
                    System.out.println("student-->"+student);//student对象
                    Method setStudentId = student.getClass().getMethod("setStudentId",String.class);//获取set方法
                    Object obj1 = setStudentId.invoke(student, "tom");//使用对象赋值
                    System.out.println("-->setStudentId-->"+setStudentId.toString()+"-->"+obj1);
                    Method getStudentId = student.getClass().getMethod("getStudentId");//获取get方法
                    Object obj2 = getStudentId.invoke(student);//使用对象取值
                    System.out.println("-->getStudentId-->"+getStudentId.toString()+"-->"+obj2);
                    
                }
            }
    
            /**    *自定义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;
                }   
                //使JavaCompiler可以从content获取java源码
                @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;   
                }
                //获取输出流为byte[]数组
                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);  
                }
            }
    
            
            public static void main(String[] args) throws Exception {
                createStudent();
            }
            
    }

    今天听到一个给属性赋值的方法比invoke效率高,记录一下

    //			java.lang.reflect.Field name = clazz.getField("name");//不能访问私有,getField用于返回一个指定名称的属性,但是这个属性必须是公有的
    //			name.set(obj, "tom");//set方法不能给私有属性赋值
    			
    			java.lang.reflect.Field name = clazz.getDeclaredField("name");//getDeclaredField方法可以得到私有属性
    			name.setAccessible(true);//若想使用set方法给属性赋值,需要设置accessible为true
    			name.set(obj, "tom");
    

      

  • 相关阅读:
    css之个人表单常用样式收藏
    oracle之序列问题集
    eclipse快捷键Two
    h5和App Native的交互方式
    Jenkins运行在Linux中,报No module namedxxxx(找不到包),如何解决
    ubuntu18 build opencv4 from source
    ubuntu无法进入图形界面可以进入终端
    ubuntu启动盘制作
    cpp_extention中nvcc命令指定gcc
    彻底删除Ubuntu EFI分区及启动项
  • 原文地址:https://www.cnblogs.com/it-mh/p/10755209.html
Copyright © 2020-2023  润新知