专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

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()));}}

iQOOZ6和RedmiNote11TPro针尖对麦芒,相差200元怎么选?看完懂了针尖对麦芒,千元市场两款销量霸主iQOO和Redmi已经发布了各自的新机,分别是iQOOZ6和RedmiNote11TPro,两款手机8GB128GB版本相差200元,对于手机小白制冰机是智商税吗?是否值得买?夏天怎么能缺少冰呢?虽然如今已经算是秋天了,但是南方还是非常地炎热,每天都是30多度的高温,除了吹空调可以降温之外,吃冰也是我们的解暑方式。制冰机,顾名思义是用来制冰的,有人可能会一图读懂百度Q2财报营收296亿元,核心研发投入超20北京时间8月30日,百度(NASDAQBIDU,HKEX9888)发布了截至2022年6月30日的第二季度未经审计的财务报告。第二季度,百度实现营收296。47亿元归属百度的净利润核心配置出众,三星GalaxyZFold4尽享旗舰大屏体验三星GalaxyZFold4的亮相,在市场上引起了不小的轰动。作为三星迄今为止功能最全面的折叠屏手机,其耐用性非常地出色。至于它还有哪些精彩的表现,一起看下文吧!核心配置十分出众三回合制战术RPG王国保卫战传奇将于7月15日发售铁皮工作室新作,肉鸽回合制战术RPG王国保卫战传奇将于7月15日在Steam发售,支持中文。这是一款战术系统深刻复杂充满冷笑话的回合制战斗RPG游戏!你能经受住前路上的一切考验,拯早知如此,宁愿她是差生,河南女生高考后遇害,亲属分析原因河南算是一个高考大省,同时也拥有着深厚的文化底蕴,不过在这片土地上,也发生着一些叫人意外又心酸的事。高考其实从不是学生自己的任务,也包含着家长甚至整个家族对后代的期望。特别是在河南官厅水库附近房子!。官厅水库附近房子!这是一个山脉与万物生长的清幽之所,这是一个历史与现代交汇的人文故乡,这是一个自然与艺术碰撞的实践梦地。有人说,大自然如此青睐原乡,把每个人的田园理想留在这里。以天北美风情录二黄石公园活火山在许多人头脑中,有一种习惯思维几乎成了定势只要一提起公园,马上就想到那是由政府出面,围一块地盘,对环境作一番人工打造后,供大众游览休闲的地方。既是用围墙围起来的,面积他的莲海世界1hr大巴车停了。随着穿统一湖蓝色外套的男男女女起身,他也很快跟着下了车。站在被太阳曝晒的停车场,风卷来阵阵热浪,他才终于想起了自己为何在这。9月24日这一天,身为博湖县大学生志愿十里花海像极了烟雨濛濛的江南2022年8月30日星期二阴天有雨特别喜欢细雨绵绵的天气,细雨绵绵,无声无息,连续下,连续下,没日没夜,像极了烟雨濛濛的江南。江南没有怎么驻足过,也不曾真切地感受过江南的烟雨天气。12GB512GB,发布仅四个月下跌600元,顶配天玑9000旗舰跌至新低不出意外的话,下半年安卓旗舰的销量终于能停止下滑,开始进入增长阶段了,自从高通接连发布骁龙888系列以及骁龙8Gen1等功耗控制不佳的旗舰处理器之后,使得安卓旗舰深受发热的影响,销
五朵金花王苏娅差点重蹈杨丽坤的悲剧,平凡丈夫温暖她一生头条创作挑战赛点击关注,每天都有名人故事感动您!王苏娅上世纪50年代至80年代,王苏娅是红极一时的电影明星,主演了猛河的黎明五朵金花战火中的青春海霞决裂七月流火海上生明月邮缘女局长乱世才女蔡文姬一代枭雄曹操心里的白月光蔡文姬,被曹操暗恋了40年,小心翼翼地守护了一辈子,曹操在如日中天的时候,为了救她,陈兵十万于西域,蔡文姬究竟有什么样的魅力让曹操做到如此?曹操,字孟德,幼时贪玩不爱读书,后来,有抗日巾帼女英雄赵一曼31岁时被日军枪毙,英雄牺牲,丈夫被诬为苏修派遣的特务叛徒,被迫害致死,儿子自缢身亡,抗日巾帼女英雄赵一曼究竟有着怎样的人生?这不仅是她家庭的悲剧,更是时代的悲剧历史的悲剧。赵一曼陕西挖出最寒酸古墓,盗墓贼都懒得下手,专家却挖出225国宝文物1992年,宝鸡的考古工作人员在勘探地貌时偶然发现了泥土里埋藏的大量朱砂,从而进一步挖掘,揭开了益门二号墓的面纱。当人们看到墓葬规格时,都有些失望,这是一个只有约3平方米的极小墓葬战争的灾难不在于枪炮吞食肉体的血睲。正义总是在良知中诞生,邪恶往往颠倒是非中孕育。3月17号,也就是周五国际海牙刑事法院对俄罗斯总统普京发出了逮捕令,全世界众说纷纭,孰是孰非地球人心中皆有分寸。我们想一想二战结束后,洋务运动文半日闲编辑半日闲前言洋务运动是中国晚清时期进行的一场以引进西方技术为主要特征的综合性现代化运动,始于1861年,止于1895年,历时三十四年之久。在这个时期,中国国内外形势激变,纵横法兰西阿尔萨斯,法德五进五出的血雨腥风在法国东北部的莱茵河畔,坐落着法国第七大城,以及最大的边境城市斯特拉斯堡,这座城市位于莱茵河的西岸,和东岸的德国城镇凯尔只有咫尺之遥。斯特拉斯堡乍一看斯特拉斯堡,这个德味十足的名字中华上下五千年长勺之战历史开讲齐桓公称霸后,鲁庄公心里极不舒服。当初,管仲明明在他手下,可齐桓公却依靠管仲的帮助做上了霸主,这让庄公更不平衡。于是,庄公开始练兵,准备与齐国比个高下。长勺之战,发生在中国红色剧本游前往南方的号召启动中国青年报客户端讯(中青报中青网记者林洁)3月16日,红色剧本游前往南方的号召在中共三大会址纪念馆启动。今年,中共三大会址纪念馆将面向以党团员为主的社会群体开展20场剧本游活动。启物流战略规划(12)物流趋势的影响1自动化及智能化物流自动化和物流智能化是未来可见的时期内,一个非常重要的趋势,它从根本上改变物流运营的成本结构。并且将人的影响降到最低,使物流这项由于环节众多参与者众多而充满变数的供应链职能,变得你的孩子虽然在看书,但并不是在真正的学习家长百问百答在大多数家长们普遍的认知里,很多人都会觉得,学习嘛,不就是看书咯。可事实真是如此吗?今天我们就一起来聊聊看书与学习的话题。对于大多数普通家长而言,看书和学习的关系,既不
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网