记得第一次接触闭包的时候,觉得很奇怪,但从字面上很那理解闭包什么玩意,和闭包有的一比的当属控制反转,真正理解了后觉得就平常了。闭包二字其实是很经典的,闭包代码所表现的东西可不就是一个封闭的、自成一体的功能块吗?简单的说,闭包就是在内部定义的方法,拿到外面去使用。经典的javascript闭包形式如下:
function f1(){
var i = 20;
function closef(x){
alert(i+x);
}
return closef
}
var s = f1();
s(20);
javascript的这种闭包形式的确相当简洁,类似于c语言的函数指针
众所周知,java实现闭包的形式是内部类,更常用的还是匿名内部类,而这通常还需要定义接口,通过接口的引用来操作内部类对象,从而实现闭包,远没有javascript简洁。这里介绍我在开发中使用的一种java闭包形式,当然还是内部类,我在实现的时候把反射机制加了进来,这么做就是尽量使用起来简单一些。代码如下:
先定义一个接口,接口还是需要的,在以后的闭包使用中,只需要这一个接口。
package p;
public interface IMethod {
public Object invoke(Object ... objects );
}
该接口的实现类,这里引入反射:
package p;
import java.lang.reflect.Method;
public class MethodObject implements IMethod {
private Object target;//闭包所依赖的对象
private String methodName;//闭包方法的名字
public MethodObject(){}
public MethodObject(Object target, String methodName) {
super();
this.target = target;
this.methodName = methodName;
}
public Object invoke(Object... objects) {
Class clazz = target.getClass();
try {
Method[] ms = clazz.getDeclaredMethods();
Method targetMethod = null;
for(Method m : ms){
if(methodName.equals(m.getName())){
targetMethod = m;
break;
}
}
targetMethod.setAccessible(true);
return targetMethod.invoke(target, objects);
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
public void rebund(Object anothertarget){
target = anothertarget;
}
}
下面是具体使用闭包的形式:
public class Person {
private int age = 0;
public Person(int age) {
super();
this.age = age;
}
public IMethod getClosualMethod(){
final int i = 10;
Object o = new Object(){
Date getBirthday(){
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR,c.get(Calendar.YEAR) - (age+i));
return c.getTime();
}
};
MethodObject mo = new MethodObject(o,"getBirthday");
return mo;
}
}
package test;
import p.IMethod;
public class Test {
/**
* @param args
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
Person p = new Person(20);
IMethod m = p.getClosualMethod();
Object o = m.invoke();
System.out.println(o);
IMethod m2 = p.getClosualMethod2();
m2.invoke("Tom");
}
}
下面是输出结果:
Sun Jun 03 17:35:05 CST 1979
hello Tom, I am 20 years old
从这里可以看到,有了Imethod和MethodObject,在java里使用闭包,就可以像javascript那样方便了。当然,这只是模拟,如果想要达到javascript那样在运行期改变对象的属性和方法,可以在更高一级去模拟。
分享到:
相关推荐
1. **闭包运算**:闭包运算是一种在集合上定义的操作,它将一个集合转换成另一个集合,使得新集合满足特定的性质。例如,自反闭包确保集合内的每个元素都与自身相关联,传递闭包确保如果A与B相关且B与C相关,则A与C...
在Java中,闭包是一种能够访问和修改其封闭作用域(创建它的环境)变量的能力的函数或代码块。这通常涉及到内部类,因为内部类可以访问其外部类的成员,即使外部类的作用域已经结束。成员内部类、局部内部类、嵌套...
Java作为一种广泛应用的编程语言,提供了丰富的工具和库来实现这些概念。 **DFA(确定有限状态自动机)**是一种接受或拒绝字符串的机器,它只有有限数量的状态,每个状态可以转移到另一个确定的状态,且对于任何...
这些规则将被转换成一种形式,以便于分析表的生成。 接下来,我们需要构建状态转移图,这是SLR(0)分析器的核心部分。这个过程涉及计算闭包(closure)和扩展(go-ahead)操作。闭包操作用于收集当前状态下所有可能...
学生提问:我是否可以让图4.13中灰色覆盖的数组元素再次指向另一个数组?这样不可以扩展成三维数组吗?甚至扩展到更多维的数组? 101 4.6.5 操作数组的工具类 102 4.6.6 数组的应用举例 103 4.7 本章小结 106 本...
Java,另一方面,是一种面向对象的、跨平台的编程语言,由Sun Microsystems(现已被Oracle收购)开发。Java的设计目标是“一次编写,到处运行”,这得益于其JVM(Java虚拟机)的特性。Java广泛应用于企业级应用开发...
EsProc提供了一种叫做AFC(Array-Flow Computation)的计算模型,将数据处理流程以流图的形式展现,使数据处理过程更加直观。它还支持多种数据源的连接,包括数据库、文件、API等,且具备并行计算能力,能够有效提升...
状态转移表描述了在解析过程中,如何根据当前输入符号将分析器的状态从一个移动到另一个;动作表则指示在特定状态下遇到特定输入符号时,分析器应执行的操作,比如 shift(将输入符号压入栈)、reduce(根据产生式...
然而,需要注意的是,这种命名空间的实现本质上仍然是全局变量的一种形式,因此如果在全局命名空间上定义过多的变量和函数,可能会导致命名冲突或者全局污染的问题。在现代JavaScript开发中,通常建议使用模块化技术...
10. **隐式转换**:Scala的隐式转换可以将一种类型自动转换为另一种类型,当需要某类型但实际提供的是另一种类型时,隐式转换可以发挥作用。 这个"快学Scala课后习题答案集合"资源将帮助学习者核对自己的解答,理解...
另一种并发设计模式是消息/事件驱动,常见于Actor模型。在这种模型中,服务请求者发送消息后继续执行,依赖于服务结果的后续流程需要在接收到响应后触发。然而,这种模式需要处理复杂的流程状态,增加了开发难度。...
LR0分析法是编译器设计领域中的一个重要概念,它是一种自底向上的解析技术,主要用于构造词法分析器和语法分析器。LR0分析法主要用于处理上下文无关文法,帮助编译器理解程序结构并进行语义分析。在这个过程中,LR0...
另一种方法是将词法分析作为语法分析的子程序,在解析过程中动态进行,这种方式可以减少内存开销,但可能增加复杂性。 正规文法、正规集和正规式是词法分析中的核心概念。正规文法是形式语言理论中的一个重要概念,...
JavaScript作为一种动态弱类型的语言,与传统的面向对象语言如Java、C++等相比,在实现面向对象方面有着自己独特的方式。 - **原型链继承**:JavaScript使用原型链实现继承机制,每个对象都有一个指向其原型对象的...
GFA是一种扩展的自动机模型,允许空转移(ε转移)的存在,这使得DFA可以通过ε闭包操作来轻松地转化为GFA。ε转移是在没有实际输入符号的情况下可以从一个状态转移到另一个状态的特殊转移。GFA的引入是为了方便后续...
4. 正则表达式引擎:虽然Java标准库已经提供了`java.util.regex`包,但Java Automata Library提供了另一种实现方式,可能在某些特定场景下更高效。 5. 机器学习:自动机可以作为特征提取器的一部分,帮助识别序列...
LR分析器是一种在编译器设计中用于解析程序语法的重要工具,主要应用于上下文无关语言。LR分析器的“L”代表自左至右扫描输入,“R”代表右most衍生树(Rightmost Derivation),而“分析表”则是LR分析器工作的核心...
JSP本质上是Servlet的另一种表现形式,JSP文件在服务器上被转换为Servlet类,然后编译成字节码执行。Servlet处理请求并生成响应,而JSP则侧重于视图展示,两者结合实现了MVC模式。 4. **JS高级编程** `JS高级编程...