【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )
2023-06-13 09:18:00 时间
文章目录
总结
在闭包中 , 打印 this , owner , delegate , 打印结果都是创建闭包时所在的类 ;
- 如果在类中创建闭包 , 则打印结果是类 ;
- 如果在实例对象中创建闭包 , 则打印结果是实例对象 ;
- 如果在闭包 A 中创建 闭包 B , this 是最外层闭包 A 之外的类 , owner , delegate 是上一层闭包 B ;
一、静态闭包变量
1、执行普通闭包变量
在类中定义闭包变量 , 在闭包中打印 this、owner、delegate 值 ,
class Test2 {
def closure = {
println "this : " + this
println "owner : " + owner
println "delegate : " + delegate
}
}
执行上述 Test2 类中的闭包 ,
new Test2().closure()
打印结果如下 : 打印的值都是 Test2 实例对象 ;
this : Test2@5082d622
owner : Test2@5082d622
delegate : Test2@5082d622
2、执行静态闭包变量
如果将闭包声明为静态变量 ,
class Test2 {
def static closure = {
println "this : " + this
println "owner : " + owner
println "delegate : " + delegate
}
}
直接使用闭包所在类直接调用闭包 , 不再使用闭包所在类对象调用闭包 ;
Test2.closure()
执行结果为 : 打印的值都是 Test2 类 ;
this : class Test2
owner : class Test2
delegate : class Test2
还是上述静态闭包变量 , 使用 Test2 实例对象调用 ,
new Test2().closure()
打印的结果是创建闭包时所在的类 ;
this : class Test2
owner : class Test2
delegate : class Test2
二、 在闭包中定义闭包
在 Test2 类中定义 闭包变量 closure2 , 在 closure2 闭包中定义 closure3 闭包 ,
class Test2 {
def closure2 = {
def closure3 = {
println "this : " + this
println "owner : " + owner
println "delegate : " + delegate
}
closure3()
}
}
打印结果如下 :
this : Test2@291a7e3c
owner : Test2$_closure1@4ae9cfc1
delegate : Test2$_closure1@4ae9cfc1
this 值为 外部的 Test2 实例对象 ;
owner 和 delegate 是 Test2 中定义的 closure2 闭包 ;
创建 closure2 闭包时 , this、owner、delegate 都是 Test2 实例对象 ;
但是创建 closure3 闭包时 , this 的值还是设置 closure2 的 this 值 , owner、delegate 值设置成 closure2 闭包 ;
// 创建内层闭包时 , 传入的 this 是 外层闭包的 this.getThisObject()
// 因此 this 值仍是 Test2 实例对象
// owner、delegate 变为外层的 Closure 闭包 ;
Object closure3 = new _closure2(this, this.getThisObject());
分析生成的字节码文件 :
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import groovy.lang.Closure;
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.transform.Generated;
import groovy.transform.Internal;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.codehaus.groovy.runtime.callsite.CallSite;
public class Test2 implements GroovyObject {
private Object closure2;
@Generated
public Test2() {
CallSite[] var1 = $getCallSiteArray();
super();
// 创建外层闭包
Test2._closure1 var2 = new Test2._closure1(this, this);
this.closure2 = var2;
MetaClass var3 = this.$getStaticMetaClass();
this.metaClass = var3;
}
@Generated
@Internal
public MetaClass getMetaClass() {
MetaClass var10000 = this.metaClass;
if (var10000 != null) {
return var10000;
} else {
this.metaClass = this.$getStaticMetaClass();
return this.metaClass;
}
}
@Generated
@Internal
public void setMetaClass(MetaClass var1) {
this.metaClass = var1;
}
@Generated
public Object getClosure2() {
return this.closure2;
}
@Generated
public void setClosure2(Object var1) {
this.closure2 = var1;
}
// 这是外层的 Closure 闭包
public final class _closure1 extends Closure implements GeneratedClosure {
public _closure1(Object _outerInstance, Object _thisObject) {
CallSite[] var3 = $getCallSiteArray();
super(_outerInstance, _thisObject);
}
public Object doCall(Object it) {
CallSite[] var2 = $getCallSiteArray();
// 这是内层的 Closure 闭包
final class _closure2 extends Closure implements GeneratedClosure {
public _closure2(Object _outerInstance, Object _thisObject) {
CallSite[] var3 = $getCallSiteArray();
super(_outerInstance, _thisObject);
}
public Object doCall(Object it) {
CallSite[] var2 = $getCallSiteArray();
var2[0].callCurrent(this, var2[1].call("this : ", this.getThisObject()));
var2[2].callCurrent(this, var2[3].call("owner : ", var2[4].callGroovyObjectGetProperty(this)));
return var2[5].callCurrent(this, var2[6].call("delegate : ", var2[7].callGroovyObjectGetProperty(this)));
}
@Generated
public Object doCall() {
CallSite[] var1 = $getCallSiteArray();
return this.doCall((Object)null);
}
}
// 创建内层闭包时 , 传入的 this 是 外层闭包的 this.getThisObject()
// 因此 this 值仍是 Test2 实例对象
// owner、delegate 变为外层的 Closure 闭包 ;
Object closure3 = new _closure2(this, this.getThisObject());
return var2[0].call(closure3);
}
@Generated
public Object doCall() {
CallSite[] var1 = $getCallSiteArray();
return this.doCall((Object)null);
}
}
}
三、 完整代码示例
完整代码示例 :
class Test2 {
// 定义静态闭包
// 即可以通过类执行
// 又可以通过对象执行
def static closure = {
println "this : " + this
println "owner : " + owner
println "delegate : " + delegate
}
// 闭包中定义闭包
def closure2 = {
def closure3 = {
println "this : " + this
println "owner : " + owner
println "delegate : " + delegate
}
closure3()
}
}
println "通过类执行闭包 :"
Test2.closure()
println "\n通过对象执行闭包 :"
new Test2().closure()
println "\n闭包中定义闭包并执行 : "
new Test2().closure2()
执行结果 :
通过类执行闭包 :
this : class Test2
owner : class Test2
delegate : class Test2
通过对象执行闭包 :
this : class Test2
owner : class Test2
delegate : class Test2
闭包中定义闭包并执行 :
this : Test2@1f010bf0
owner : Test2$_closure1@40db2a24
delegate : Test2$_closure1@40db2a24
相关文章
- PHP递归函数内的静态变量
- static–静态变量与普通变量的区别
- EasyC++46,静态持续变量
- Spring @Autowired 注解静态变量
- 方法区(Method Area)存储的静态变量[通俗易懂]
- 21.Go语言-静态类型与动态类型
- 【说站】如何解决WordPress伪静态打开内页404错误
- 面试官问:静态变量、实例变量在JVM内存区域是怎么布局的?线程安全吗?
- 详解java中静态方法有哪些_java类中的静态变量
- php源码审计_静态代码审计
- PyTorch模型静态量化、保存、加载int8量化模型
- 使用gulp-replace实现全局替换hexo静态文件jsd cdn加速链接(包括插件)
- Nginx 静态资源部署
- 实验(五)第一部分:指定静态库
- 【C 语言】内存管理 ( 动态内存分配 | 栈 | 堆 | 静态存储区 | 内存布局 | 野指针 )
- PHP 使用静态变量(static var)进行效率优化
- 使用静态内部类实现单例设计模式详解编程语言
- C++静态成员变量详解
- 深度探索Linux下的静态库与动态库(linux静态库与动态库)
- Linux静态加载:实现无缝切换(linux静态加载)
- 深入理解Oracle中的静态游标(oracle静态游标)
- 用PHP实现WEB动态网页静态
- php静态变量的初始化
- php静态变量与自定义常量的使用方法
- javascript新闻标题静态分页代码(无刷新)
- 非常精妙的PHP递归调用与静态变量使用
- java中静态变量和实例变量的区别详细介绍
- Android静态变量的生命周期简单介绍
- 关于C++静态成员函数访问非静态成员变量的问题
- jsp中include指令静态导入和动态导入的区别详解
- php中的静态变量的基本用法
- Python使用函数默认值实现函数静态变量的方法