游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

Java源代码动态编译类加载和代码执行(Java8)

  头条创作挑战赛
  Java的一个重要特性是动态的类加载机制。通过在运行时动态地加载类,Java程序可以实现很多强大的功能。下面通过一个具体的实例来说明Java程序中,如何动态地编译Java源代码、加载类和执行类中的代码。这里的代码示例适用的版本是Java8。
  示例所实现的功能很简单,就是对表达式求值。输入的是类似11或3(23)这样的表达式,返回的是表达式的值。示例的做法是动态创建一个Java源文件,编译该文件生成class文件,加载class文件之后再执行。比如,需要求值的表达式是11,那么所生成的Java源文件如下所示,其中11的部分是动态的。publicclassCalculator{publicstaticObjectcalculate(){return11;}}
  我们只需要编译该源文件,加载编译之后的class文件,再通过反射API来调用其中的calculate方法就可以得到表达式求值的结果。编译
  第一步是动态生成Java源代码并编译。生成Java源代码比较简单,直接用字符串连接就可以了。当然了,在生成逻辑比较复杂时,推荐的做法是使用字符串模板引擎,如Handlebars。在下面的代码中,getJavaSource方法生成Java源代码,compile方法进行编译。
  在进行编译的时候,使用的是JDK标准的JavaCompiler接口。从源代码字符串中创建了一个JavaFileObject对象作为编译时的源代码单元。编译时的选项d指定了编译结果的输出路径,这里是一个临时文件夹。compile方法的返回值是一个Pair对象,包含了class文件的路径,以及随机生成的Java包的名称。publicclassDynamicCompilation{privatestaticfinalStringCLASSNAMECalculator;publicstaticPairPath,Stringcompile(Stringexpr)throwsIOException{StringpackageNamezUUID。randomUUID()。toString()。replace(,);PathoutputPathFiles。createTempDirectory(expr);JavaCompilercompilerToolProvider。getSystemJavaCompiler();StandardJavaFileManagerfileManagercompiler。getStandardFileManager(null,null,null);compiler。getTask(null,fileManager,null,ImmutableList。of(d,outputPath。toAbsolutePath()。toString()),null,Collections。singletonList(newStringContentJavaFileObject(CLASSNAME,getJavaSource(packageName,expr))))。call();returnPair。of(outputPath,packageName。CLASSNAME);}privatestaticStringgetJavaSource(StringpackageName,Stringexpr){returnpackagepackageName;publicclassCLASSNAME{publicstaticObjectcalculate(){returnexpr;}};}}
  上面的代码用到了一个帮助类StringContentJavaFileObject,表示从字符串创建的JavaFileObject对象。publicclassStringContentJavaFileObjectextendsSimpleJavaFileObject{privatefinalStringcontent;publicStringContentJavaFileObject(Stringname,Stringcontent){super(URI。create(string:nameKind。SOURCE。extension),Kind。SOURCE);this。contentcontent;}OverridepublicCharSequencegetCharContent(booleanignoreEncodingErrors){returncontent;}}
  加载
  编译完成之后的第二步是动态加载类。这一步并没有实现自定义的类加载器,而且使用内置的系统类加载器。系统类加载器通过ClassLoader。getSystemClassLoader()方法来获取。系统类加载器在classpath上查找类。这里用了一个比较hack的技巧来动态修改系统类加载器的classpath。
  在下面的代码中,ClasspathUpdater的addPath方法可以把一个Path对象表示的路径,添加到系统类加载器的查找路径中。这是因为系统类加载器自身是URLClassLoader类型的加载器,其中的addURL方法可以添加新的查找路径。只不过addURL方法是protected,这里通过反射API来进行调用。publicclassClasspathUpdater{publicstaticvoidaddPath(Pathpath){URLClassLoaderclassLoader(URLClassLoader)ClassLoader。getSystemClassLoader();try{MethodmethodURLClassLoader。class。getDeclaredMethod(addURL,URL。class);method。setAccessible(true);method。invoke(classLoader,path。toUri()。toURL());}catch(Exceptione){thrownewRuntimeException(e);}}}
  上面介绍的ClasspathUpdater类中的使用技巧,只对Java8生效。在Java9引入模块系统时,对系统类加载器进行了修改。系统类加载器被替换成了应用类加载器。应用类加载器不再是URLClassLoader类型了,就不能使用这个技巧了。执行
  最后一步就是执行动态加载的Java类。这一步比较简单,只需要用Class。forName方法来查找Java类,再找到对应的Method对象,直接调用即可。下面的代码给出了示例。publicclassInvoker{publicstaticObjectinvoke(StringclassName){try{MethodmethodClass。forName(className)。getDeclaredMethod(calculate);returnmethod。invoke(null);}catch(Exceptione){thrownewRuntimeException(e);}}}完整的执行过程
  最后把整个流程串起来。在下面的代码中,需要求值的表达式是(11)35。0。首先调用DynamicCompilation。compile方法进行动态编译,得到class文件的路径和完整的类名。class文件的路径通过ClasspathUpdater。addPath方法添加到classpath中。完整的类名则传递给Invoker。invoke方法来执行。最后输出的结果是表达式的值。publicclassMain{publicstaticvoidmain(String〔〕args)throwsIOException{PairPath,StringresultDynamicCompilation。compile((11)35。0);ClasspathUpdater。addPath(result。getLeft());System。out。println(Invoker。invoke(result。getRight()));}}

今明两年不买房,3年后是买不起还是随便挑?这下清楚了在刚过去的一季度,根据中国房地产报统计,百强房企市值依然处于下跌态势,百强房企市值总和环比2022年末缩水超1700亿元,跌幅超4,四成房企市值不足200亿元。在2020年之前……谨以此文纪念我不寻常的十一月这个十一月对我一点都不友好。我素来不信什么因果报应,但是这个11月二十来天的经历,真的让我对命运二字有了新的认识。10月30日,在我的要求下,我去医院做了引产,之后……联想上架小新Pro132020款i5MX350,5899元IT之家3月17日消息今日下午,联想正式上架了小新Pro132020款,搭载英特尔i510210U处理器,采用MX350显卡,首发价5899元,将于明日(3月18日)零点开启预……如何克服过度思考如何克服过度思考?1。改变对自己说话的方式,过度思考者总是不停的对自己说负面信息,如果你总是对自己说我永远不会准时,我无法完成任何事情你的大脑就会相信那是真的,因为你总是……联想小新Pro1320203月24日开卖i510210UMXIT之家3月11日消息今天晚上,联想官方宣布小新Pro132020将于3月24日开卖,首发Corei510210U16GB512GBMX350配置,价格尚未公布。联想小新……她最近经常爱打扮,频繁换衣服,是不是有什么情况?曾经有位家长跟我叙述了这样一件事:我女儿正在上高三,个子不怎么高,她平时兴趣爱好很多,比如唱歌、玩滑板、跳街舞,等等。最近,我发现女儿越来越讲究穿着。她喜欢穿新衣服、新鞋……联想拯救者Y7000竞技版明天开卖i59300HFGTX16IT之家3月9日消息3月3日,联想拯救者发布了Y7000竞技版,搭载了无核显处理器,i59300HF8G512GGTX1650售价5699元,3月10日开卖。IT之家了解……联想公布拯救者Y9000K2020款15。6英寸,单键RGBIT之家3月6日消息今天晚上,联想产品经理林林在微博中公布了拯救者Y9000K2020款的部分信息,今年新款将会搭载15。6英寸屏幕,单键RGB键盘也安排上了。联想拯救者……联想小新Pro132020将搭载MX350独显,其余配置不变IT之家3月4日消息联想去年发布的小新Pro13将更新2020款,今天联想官方宣布小新Pro132020将搭载MX350独显,其余配置不变。IT之家了解到,联想小新Pro……联想拯救者Y7000竞技版上架独显直连,LOL帧数提升34IT之家3月3日消息联想拯救者Y7000竞技版现已上架,i59300HF8G512GGTX1650售价5699元,3月4日开启预售,3月10日开卖。IT之家了解到,拯救者……无核显游戏本来了联想公布拯救者Y7000竞技版,首发5699IT之家3月3日消息根据联想拯救者官方的消息,联想将推出拯救者Y7000竞技版,搭载i59300HF无核显处理器,8G512G1650高色域版本首发价格5699元。IT之……老年人应该坚持做好以下几件事,或许能更好的保障身体健康1、经常散步对于老年人来说散步是最为适合的运动方式,因为散步强度不大,而且也属于有氧运动。每天坚持锻炼40分钟左右的时间,不光能够促进脂肪燃烧,控制体脂率,同时还能……
每天坚持吃1个鸡蛋,对身体是好是坏?会升高胆固醇吗?真相来了邻居王大爷每周都会去超市购买鸡蛋,平日里也总是和邻居介绍道,这鸡蛋看似普通,实则学问很深。鸡蛋其实是养生蛋,每天吃一个,不仅增进营养,还能延年益寿呢。可是他的老伴就不赞同了,觉……冰雪传奇手游侠客冰雪之义战龙城全新侠客系统,震撼来袭大家好啊,今天给大家带俩一款冰雪传奇手游《侠客冰雪之义战龙城》。这款手游顾名思义就是开放了全新的侠客系统,感兴趣的小伙伴可以私信小编下载哦每个人小时候都有一个武侠梦,小时……商丘公交公司已成被执行人因劳动争议被执行4715元新京报贝壳财经讯2月23日,商丘公交微信公众号发布通告,受疫情冲击、国家新能源补贴政策调整、财政补贴不到位等多种因素叠加影响,导致目前公司亏损十分严重,经营异常困难,经公司研究……为什么用小米的几乎很少会买OV,而用OV的也几乎不会买小米呢国内手机市场一直被华为、小米、OPPO、VIVO这几大手机品牌占据。抛开华为不谈,相信使用小米和OV的人已经有几亿人了,但很多米粉表示换机选苹果也不选OV,而OV粉则表示坚决不……CBA三消息广东外援暂不退役,王少杰狂练力量,郭昊文自动参选爱国篮,爱CBA,我是洛姐,小伙伴们看完记得点赞!这个赛季广东队在季后赛半决赛中被辽宁队横扫淘汰出局,对于广东队来说,这个成绩并不是特别理想,但是球队确实也没有什么办法,……泰国著名的毒奶按摩店,用户笑着进去哭着出来,回头客多我国的经济实力越来越强悍,对于大众来说,人们的生活水平发生改变之后,很多小伙伴开始追求精神层次,而精神层次主要是精神方面的享受。其中有部分小伙伴为了提高自身的精神层次,来……聊新能源车不提丰田,是一件非常不礼貌的事情!过去30年的中国乘用车市场发展,从来没有像今天一样关注到汽车安全。燃油车时代,我们对安全的理解就是车身结构安全,所以我们有日德之争,才会有针对吸能设计是否合理的激烈讨论。……德约科维奇丢人了!网坛名将直言德约球风不如费德勒纳达尔好看12月26日,号称地表最强170的网球名将施瓦茨曼在接受采访时谈到了他眼中的三巨头,在过去相当长一段时间里,人们特别喜欢讨论费德勒、纳达尔和德约科维奇到底谁最受欢迎的话题,德约……为什么出现量子力学之后现代物理学近百年都没有什么进展?一百年以前,爱因斯坦开创性地提出了相对论的学说,普朗克等人也提出了很多量子学说的基础理论,从此物理学从传统物理学走进了现代物理学的时代。但是从那次爆炸性的进步之后,物理学……陈数与老公合体亮相真隆重,穿金色宫廷风长裙像贵妇,你觉得呢?陈数这就是这样一个容貌、身材、气质兼备的女人,她的长相可以说是非常柔和大气,笑起来也是那种笑容,她不是那种乍一看就惊艳的类型,而是越看越有魅力的类型,也就是说,这种女性气质尤为……最佳补肾季3个食方,助你彻底补漏原创惠娴少点盐早上好已经到了要好好冬藏的时候了呢。今年比较特殊,夏日太炎热秋天过于燥。对于本来就有些虚的小伙伴来说,是一重不小的考验:抵抗力下降、总是很……NBA动态!勇士国王裁判报告出炉勇士获利,欧文获萧华谅解北京时间11月9日,今日无NBA比赛,让我们来看下NBA相关动态吧!1,勇士国王裁判报告:漏吹库里走步克雷关键犯规北京时间11月9日,NBA官方公布了昨日勇士险胜国……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网