groovy——运行方式、基本语法、引入方式、metaClass
jvm运行groovy类有两种方式:
1.使用groovyc编译所有的*.groovy为java的*.class文件,把这些*.class文件放在java类路径中,通过java类加载器来加载这些类。
2.通过groovy的类加载器在运行时直接加载*.groovy文件并且生成对象,在这种方式下,没有生成任何*.class,但是生成了一个java.lang.Class对象的实例,也就是说,当groovy代码中包括一个new MyClass()的表达式时,并且也有一个MyClass.groovy的文件,这个文件将被解释,一个MyClass的类型将被产生并且增加到类加载器中,在代码中将像从*.class一样获取到MyClass对象。
没有生成.class文件也可以用生成class对象的实例?
没错,实际上只要有符合虚拟机规范的二进制字节流被解析成方法区的数据结构就可以生成class对象,具体可以看一下类的加载过程。
https://blog.csdn.net/iteye_7617/article/details/82474191
https://www.cnblogs.com/amosli/p/3970810.html
groovy基本语法:
https://www.cnblogs.com/amosli/p/3970810.html
引入方式:
https://www.jianshu.com/p/e8dec95c4326
1.GroovyClassLoader:运行时加载groovy代码,生成.class对象
GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
String scriptText = "class Hello { void hello() { println 'hello' } }";
//将Groovy脚本解析为Class对象
Class clazz = groovyClassLoader.parseClass(scriptText);
//Class clazz = groovyClassLoader.parseClass(new File("script.groovy"));
assertEquals(clazz.getName(),"Hello");
clazz.getMethod("hello").invoke(clazz.newInstance());
2.GroovyScriptEngine:运行时加载脚本,并监听脚本变化,当脚本发生变化时重新加载,这个厉害了啊
groovy.util.GroovyScriptEngine 类为 GroovyClassLoader 其上再增添一个能够处理脚本依赖及重新加载的功能层, GroovyScriptEngine可以从指定的位置(文件系统,URL,数据库,等等)加载Groovy脚本
可以使用一个CLASSPATH集合(url或者路径名称)初始化GroovyScriptEngine,之后便可以让它根据要求去执行这些路径中的Groovy脚本了.GroovyScriptEngine同样可以跟踪相互依赖的脚本,如果其中一个被依赖的脚本发生变更,则整个脚本树都会被重新编译和加载。
//script/groovy/hello.groovy
println "hello $name"
GroovyScriptEngine scriptEngine = new GroovyScriptEngine("script/groovy");
Binding binding = new Binding();
binding.setVariable("name", "groovy");
while (true){
scriptEngine.run("hello.groovy", binding);
TimeUnit.SECONDS.sleep(1);
}
3.GroovyShell:这种看起来不是很实用...
GroovyShell shell = new GroovyShell();
//可以绑定更多变量
shell.setVariable("age",22);
//直接求值
shell.evaluate("if(age < 18){'未成年'}else{'成年'}");
//解析为脚本,延迟执行或者缓存起来
Script script = shell.parse("if(age < 18){'未成年'}else{'成年'}");
assertEquals(script.run(), "成年");
//可以从更多位置加载/执行脚本
//shell.evaluate(new File("script.groovy"));
//shell.evaluate(new URI("http://wwww.a.com/script.groovy"));
还可以这样:
GroovyShell shell = new GroovyShell();
Script scrpt = shell.parse("script.groovy"); Binding binding = new Binding();
binding.setVariable("str1", "value1");
binding.setVariable("str2", "value2"); scrpt.setBinding(binding);
System.out.println(scrpt.evaluate("customConcat(str1, str2)")); script.groovy: def customConcat(def str1, def str2) {
str1.concat(str2)
}
4.Eval:这种是对GroovyShell的封装
Binding binding = new Binding();
GroovyShell shell = new GroovyShell(binding);
Script scrpt = shell.parse("script.groovy");
binding.setVariable("str1", "value1");
binding.setVariable("str2", "value2");
binding.setVariable("newConcat", scrpt);
System.out.println(scrpt.evaluate("newConcat.customConcat(str1, str2)"));
metaClass:
运行期添加静态方法和普通方法
https://blog.csdn.net/walkcode/article/details/24587457
groovy代码和class文件的对应关系:
https://blog.csdn.net/jiangqian6481/article/details/83717442
1.对于没有任何类定义
如果Groovy脚本文件里只有执行代码,没有定义任何类(class),则编译器会生成一个Script的子类,类名和脚本文件的文件名一样,而脚本的代码会被包含在一个名为run的方法中,同时还会生成一个main方法,作为整个脚本的入口。
2.对于仅有一个类
如果Groovy脚本文件里仅含有一个类,而这个类的名字又和脚本文件的名字一致,这种情况下就和Java是一样的,即生成与所定义的类一致的class文件, Groovy类都会实现groovy.lang.GroovyObject接口。
3.对于多个类
如果Groovy脚本文件含有一个或多个类,groovy编译器会很乐意地为每个类生成一个对应的class文件。如果想直接执行这个脚本,则脚本里的第一个类必须有一个static的main方法。
4.对于有定义类的脚本
如果Groovy脚本文件有执行代码, 并且有定义类, 那么所定义的类会生成对应的class文件, 同时, 脚本本身也会被编译成一个Script的子类,类名和脚本文件的文件名一样
如何使用groovyc 和 groovy:
https://blog.csdn.net/Leon1509/article/details/83681907
groovy——运行方式、基本语法、引入方式、metaClass的更多相关文章
- 前端基础----CSS语法、CSS四种引入方式、CSS选择器、CSS属性操作
一.CSS语法 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. 例如: h1 {color:red; font-size:14px;} 二.CSS四种引入方式 1,行内式 行内式是在标 ...
- {前端CSS} 语法 Css的几种引入方式 css选择器 选择器的优先级 CSS属性相关 背景属性 边框 CSS盒子模型 清除浮动 overflow溢出属性 定位(position)z-index
前端CSS CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素,给HTML设置样式,让它更加美观. 当浏览器读到一个样式表,它就会按照这个样式表来对文 ...
- 前端-CSS-初探-注释-语法结构-引入方式-选择器-选择器优先级-01(待完善)
目录 CSS(Cascading Style Sheet) CSS注释 CSS语法结构 CSS的三种引入方式 选择器 伪类.伪元素选择器速查 CSS选择器优先级***** 选择器相同的情况下 选择器不 ...
- Javascript用途,语法特点,难点,调试工具,引入方式,命名规范,变量声明及赋值,数据类型,运算符
JavaScript用来干什么 数据的验证 将动态的内容写入到网页当中(ajax) 对事件做出相应 读写html当中的内容 检测浏览器 创建cookies 模拟动画 语法特点 基于对象和事件驱动的松散 ...
- Groovy语言学习--语法基础(4)
语法基础到此就结束了,毕竟其和Java许多地方并无差别.groovy作为脚本,是为了能更好地随业务变化调整规则,我根据自己对规则的理解 通过一张图简单描述一个groovy脚本场景:由于货币膨胀,经济收 ...
- 《网页设计基础——CSS的四种引入方式详解》
网页设计基础--CSS的四种引入方式详解 一.行内式: 规则: 1. 行内式是所有样式方法中最为直接的一种,它直接对HTML的标记使用style属性,然后将CSS代码直接写在其中. 格 ...
- 【JavaScript的引入方式】
javascript: 是基于对象和事件驱动的客户端脚本[组成] Bom:浏览对象模型(与浏览器交互的方法和接口) Dom:文档对象模型(处理网页内容的方法和接口) ecma:核心(描述了js的语 ...
- 关于CSS引入方式的详细见解
关于CSS的发展史这里不做介绍.写博客的原因之一是想帮助那些与我一样喜欢纠结的初入前端的伙伴,希望自己写的帖子能对伙伴有些许帮助:原因之二这些帖子也算自己的一个知识的整理.现在还没有一定的顺序可循,但 ...
- web前端(13)—— 了解JavaScript,JavaScript的引入方式
从本篇博文开始,将进入web前端方便最关键最重要的部分——javascript,学到后面你就知道它真的太重要了 什么是JavaScript JavaScript一种直译式的脚本语言,是一种动态类型.弱 ...
随机推荐
- Sql--IDENTITY()自动增长列
CREATE TABLE Tables( , ) ,) NOT NULL, [UpdateTime] [datetime] NOT NULL, CONSTRAINT [PK_Tables] PRIMA ...
- 理解java中的值传递与“引用传递”
额....java中其实没有引用传递 对于引用类型 ,在调用方法后,直接拷贝了引用的副本,但是它们指向了相同的堆地址,所以看起来像引用传递,但其实是值传递,只不过传递的引用的副本. 说一说为什么Str ...
- 干掉MessageBox,自定义弹出框JMessbox (WindowsPhone)
先上效果图 QQ退出效果 ...
- asp.net 设置分页
private const int PAGESIZE = 5; //定义每页有五行数据 private void FillPageList() { int pageCount = 0; // page ...
- unix网络编程 str_cli epoll 非阻塞版本
unix网络编程 str_cli epoll 非阻塞版本 unix网络编程str_cli使用epoll实现讲了使用epoll配合阻塞io来实现str_cli,这个版本是配合非阻塞io. 可以看到采用非 ...
- 为什么 kubernetes 天然适合微服务 (3)
此文已由作者刘超授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验 四.Kubernetes 本身就是微服务架构 基于上面这十个设计要点,我们再回来看 Kubernetes,会发现 ...
- 【01】循序渐进学 docker:到底是啥
写在前面的话 首先说一下,我本身是做运维的,4 年工作,多家公司.所以可能接下来谈到的更多的是一些在工作过程中积累的个人看法.且有些并不具备普遍性,有不合适的地方,全当我在吹牛逼就行. 一开始我们得谈 ...
- Can't install Solaris 10 on XenServer 6.5 VM
I have XenServer 6.5 installed on a server, and i have been trying to install Solaris 10 on a VM, it ...
- kali linux之本地提权
已实现本地低权限帐号登录,希望获取更高权限,实现对目标进一步控制 系统帐号之间权限隔离(操作系统安全的基础,用户空间,内核空间) 系统帐号(用户帐号登录时获取权限令牌,服务帐号无需用户登录已在后台启动 ...
- CAP理论中的P到底是个什么意思
在CAP理论中,C代表一致性,A代表可用性(在一定时间内,用户的请求都会得到应答),P代表分区容错.这里分区容错到底是指数据上的多个备份还是说其它的 ? 我感觉分布式系统中,CAP理论应该是C和A存在 ...