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");
Java——动态创建Class(不写入文件,直接从内存中创建class)的更多相关文章
- In-Memory:在内存中创建临时表和表变量
在Disk-Base数据库中,由于临时表和表变量的数据存储在tempdb中,如果系统频繁地创建和更新临时表和表变量,大量的IO操作集中在tempdb中,tempdb很可能成为系统性能的瓶颈.在SQL ...
- 用ASP创建API。NET Core (Day2):在ASP中创建API。网络核心
下载PDF article - 1.5 MB 下载source - 152.4 KB 下载source - 206.3 KB 下载source code from GitHub 表的内容 中间件路线图 ...
- Java语言中:float、double数据类型在内存中是如何存储的
引用参考 https://www.cnblogs.com/chenmingjun/p/8415464.html#4291528 https://blog.csdn.net/yansmile1/arti ...
- java关于StringBuffer和StringBuilder写入文件的效率问题
StringBuffer在存储字符的时候,是有上限的,一旦达到上线就会出错,自己在项目中遇到一个从数据库中查询数据,然后写入到本地文件中 ,数据量大概有30万条,此时的效率十分的低.下面是大致的模拟该 ...
- 使用java NIO及高速缓冲区写入文件
byte[] bytes = Files.readAllBytes(Paths.get("E:\\pdf\\aaa\\html\\text.txt").normalize()); ...
- php对象在内存中创建于释放
<?php /** * 1.对象的创建占用内存, * 对象内存释放,析构方法就是在对象释放前运行最后的一步.可以自动释放和手动释放 * 手动释放:通过unset($p);来释放对象,在这个时候会 ...
- c#内存中创建反射
代码 IWFP_SYS_Bytes mywfpbyte; /**/ byte[] bin=null; using (FileStream fs = new FileStream(filename, F ...
- java中的各种数据类型在内存中存储的方式
原文地址:http://blog.csdn.net/aaa1117a8w5s6d/article/details/8251456 1.Java是如何管理内存的 java的内存管理就是对象的分配和释放问 ...
- Java的各类型数据在内存中分配情况详解
1. 有这样一种说法,如今争锋于IT战场的两大势力,MS一族偏重于底层实现,Java一族偏重于系统架构.说法根据无从考证,但从两大势力各自的社区力量和图书市场已有佳作不难看出,此说法不虚,但 ...
随机推荐
- 开发AI+诊疗生发系统,「先锋汇美」借力人工智能辅助诊疗实现头皮医学检测...
困扰年轻人的脱发问题萌生了新兴的产业链.36氪先前曾剖析过近来火热的植发市场,更多人则选择"防范于未然","头皮检测"服务备受关注.此前,人们对"头皮 ...
- 老男孩教育每日一题-2017年3月29日-使用ifconfig取出网卡eth0的ip地址-看看你有多少方法...
方法1:sed命令 [root@oldboyedu ~]# ifconfig eth0 |sed -n '2p' |sed's#^.*addr:##g'|sed 's# B.*$##g' 10.0. ...
- Facebook发布神经蛋分离法,可从嘈杂环境中提取音视频
分离混合分布是机器学习和信号处理的长期挑战,而Facebook近日提出的新方法似乎可以有效解决这一难题. 人类天生善于分离个别声音和视觉效果,例如在拥挤的鸡尾酒会上听到别人的声音,或者在动物穿过灌木丛 ...
- 外媒解读Web安全核心PKI的四大致命问题
Web安全的立足根基在于复杂的PKI部署体系,但实际生活中得到正确部署的比例却非常有限,而且这一切都将随着摩尔定律的滚滚洪流灰飞烟灭. 我个人算是PKI(即公共密钥基础设施)的忠实拥护者.我热爱数学与 ...
- Spring PropertyPlaceholderConfigurer类载入外部配置
2019独角兽企业重金招聘Python工程师标准>>> 通常在Spring项目中如果用到配置文件时,常常会使用org.springframework.beans.factory.co ...
- 家用PC机打造VSphere5.1 测试环境:之部署VCenter Server 5.1
家用PC机打造VSphere5.1 测试环境前言:实践出真知,同样学习VMware VSphere 的朋友,也需要不断的测试总结,再测试再总结只有不断的积累才能学好,但是动辄几万的服务器不是所有朋友都 ...
- Nmon 监控性能分析
一.CPU 信息 1.折线图中蓝线为 cpu 占有率变化情况:粉线为磁盘 IO 的变化情况: 2.下面表各种左边的位磁盘的总体数据,包括如下几个: Avg tps during an interval ...
- 利用github的webhook进行自动部署
利用github的webhook进行自动部署 github提供了webhook功能,大概意思就是,当你提交了代码,git检测到你进行了push,可以调起你一个你知道的url. 这个功能有什么用了?比如 ...
- python学习笔记-零碎知识点
1. 绝对值 abs(-4) 结果: 4 2.
- JDBC05 ResultSet结果集
ResultSet结果集 -Statement执行SQL语句时返回ResultSet结果集 -ResultSet提供的检索不同类型字段的方法,常用的有: getString():获得在数据库里是var ...