读书人

兑现java闭包的另一种形式

发布时间: 2012-10-25 10:58:57 作者: rapoo

实现java闭包的另一种形式

? 记得第一次接触闭包的时候,觉得很奇怪,但从字面上很那理解闭包什么玩意,和闭包有的一比的当属控制反转,真正理解了后觉得就平常了。闭包二字其实是很经典的,闭包代码所表现的东西可不就是一个封闭的、自成一体的功能块吗?简单的说,闭包就是在内部定义的方法,拿到外面去使用。经典的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 blockthrow 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 stubPerson 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那样在运行期改变对象的属性和方法,可以在更高一级去模拟。

读书人网 >软件架构设计

热点推荐