Groovy基础

这里整理了Groovy的主干知识点,适合已熟悉JAVA前提下的快速入门,这里讲述都是其核心概念,无法绕过的内容,而对于那些语法糖,花哨功能,跟java的语法差异等等,这里就不多描述了,毕竟原理都相同语法不一样而已,需要的时候看下doc套用就可以了。


1、类名和文件名可以不同,后缀为groovy




2、定义变量,基本数据类型和java一样,可以不写;号,访问权限默认public,如果类型确定则注明类型即可,类型不确定则用def name即可,方法返回类型同理:



3、定义方法,访问权限默认public,返回值类型默认是Object泛型,但是不必写return,返回类型会自动转换,例如返回‘OK’,则直接写即可



4、定义主方法,实例化对象并调用方法,println相当于System.out.println(),这是一个dsl语句,实质上就是函数领域化,System的一些方法在groovy里面是默认领域化的。

又如:


5、一个领域化的例子,导入某个类的静态方法,然后直接通过方法名调用之,注意import的方法没有()号,因为()被作用为调用方法。使用范围优先级类似于servlet中的page-request-session-context,本类的成员静态方法是不用导入的,方法领域化是将方法作为属性对待,即attribute,借助范围来解决命名冲突的:

--------------------------------------------------------------------------------


6、另外,方法领域化可以为方法起一个别名,进一步解决导入的命名冲突,如:




7、上面的写法大都是静态写法,我们来点动态的操作,如动态方法调用,这里有两个sayhello重载的方法,而我们不必知道这两个方法就可以直接call sayhello方法,如果找不到该方法会抛出异常,否则会调用该方法,如果方法存在重载,则根据入参自动调用对应的方法,如果重载中有一个是无参的方法,优先是调用有参的方法,不管是否提供参数:

这些方法都是隐式调用的,如果还需要调用sayhell()这么一个无参的方法,则需要如java的写法hello.sayhello()调用,或者say.call()显示调用,方法指针操作符(&)调用用于将一个方法的引用存储在变量中,以便以后调用它;

我们将方法打印一下,可以看出调用的是同一个对象,其实这个对象就是一个闭包对象Closure,在这个闭包中调用对应的其他方法。在java中只能实现类级及以上的闭包,不能做方法闭包,Groovy也不能在方法中定义方法,其方法闭包是通过闭包对象实现的,



8、具体的闭包实现:

闭包的定义语法{ [args] -> statement },有参数和执行内容组成,两者由->隔开,多个参数用,号隔开:


可以看到闭包是一个类型,即groovy.java.Closure闭包类,直接通过闭包名隐式调用或加上call显式调用,另外,还可以使用隐式参数


可以看到,it是隐式参数的关键字,这样就不必声明参数,其实相当于下面的写法:


又如,使用内插字符串:


9、闭包的owner,delegate,this,来看代码就明白了,所谓调用者感知

/**
* @author yl  
*
*    
*/
class Hello {
	
	class InnerClass{
		String name = 'Tom';
		
		//该闭包所属的对象
		def whoIsOwner = {at ->owner}
		def whoIsOwner2 = {getOwner()}
		
		//当前正在调用该闭包的对象
		def whoIsThis = {this}
		def whoIsThis2 = {getThisObject()}
		
		
		//委托该闭包的对象
		//显式的委托
		def whoIsDelegate = {delegate.name}
		def whoIsDelegate2 = {getDelegate().name}

		//隐式的委托		
		def say = {println "my name is ${name}"}
		
	}
	
	class NestedClass{
		String name = 'Mary'
	}
	
	def output() {
			def inner = new InnerClass()
			assert inner.whoIsOwner()== inner //true
			assert inner.whoIsOwner2() == inner //true
			
			assert inner.whoIsThis() == inner //true
			assert inner.whoIsThis2() == inner //true
			assert inner.whoIsThis2() == this //false the 'this' is the current Object that who Calling output method 
			
			assert inner.whoIsDelegate() == 'Tom' //true
			assert inner.whoIsDelegate2() == 'Tom' //true
			
			//将闭包whoIsDelegate的委托修改为nested
			def nested = new NestedClass()
			inner.whoIsDelegate.delegate = nested
			assert inner.whoIsDelegate() == 'Mary' //true
			
			//将闭包say的委托修改为nested
			inner.say()
			inner.say.delegate = nested
			inner.say()
			
			//设置闭包say的委托策略为委托者优先
			inner.say.resolveStrategy = Closure.DELEGATE_FIRST
			inner.say()			
			
			println inner.whoIsOwner
			println inner.whoIsOwner()
	}
	
	static void main(def args) {
		Hello hello = new Hello()
		hello.output()
	}
}

层次结构如下:


this:其中的this跟java的意义相同,表示正在调用你的当前对象,官方文档描述似乎有问题:this corresponds to the enclosing class where the closure is defined。其实因为闭包对象参数不能使用this,所以内部一般不可能直接访问到owner以外的调用者,因此下此定义。

owner:这个也和java的意义相同,只不过在java中没有一个特性描述这一点,owner表示拥有你的对象,但这个对象不一定是正在调用你的对象

delegate:关键的一点就是delegate(委托)对象,表示借用该闭包的的对象,可以理解为换了汤不但换药,汤就是委托对象的部分,药就是该闭包的部分。但是不能理解为this,这跟谁喝汤与汤药搭配的两码事。

Groovy中的Closure类提供了上面这三个默认属性,并且提供了方法来获取他们:getThisObject(),getOwner(),getDelegate()跟三者对应。


闭包对象的委托策略决定了执行委托者和owner的请求优先级,对隐式的委托起作用:

  • Closure.OWNER_FIRST is thedefault strategy. If a property/method exists on theowner, then it will be called onthe owner. If not, then thedelegate is used.

  • Closure.DELEGATE_FIRST reverses the logic: thedelegate is used first, then the owner

  • Closure.OWNER_ONLY will only resolve the property/method lookup on the owner: the delegate will be ignored.

  • Closure.DELEGATE_ONLY will only resolve the property/method lookup on the delegate: the owner will be ignored.

如果你使用过java的Thread.currentThread.getStackTrace()或者new Throwable().getStackTrace(),应该对调用者感知特性不陌生,在这之前还有 sun.reflect.Reflection,可以实现类似上述委托策略的调用者感知操作,但是该方法被否决过很多次,原因是影响了程序的健壮性,故java一致没有将sun包的东西标准化,后续的版本也废弃了该方法,但是该方法任然是groovy的一个主力方法,所以受影响也比较大。不过我觉得只要能保证安全的情况下,使用都无妨,视场合而定。


先整理到此,后续更新。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值