浏览 3176 次
锁定老帖子 主题:实现java闭包的另一种形式
精华帖 (0) :: 良好帖 (1) :: 新手帖 (4) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-03
记得第一次接触闭包的时候,觉得很奇怪,但从字面上很那理解闭包什么玩意,和闭包有的一比的当属控制反转,真正理解了后觉得就平常了。闭包二字其实是很经典的,闭包代码所表现的东西可不就是一个封闭的、自成一体的功能块吗?简单的说,闭包就是在内部定义的方法,拿到外面去使用。经典的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
从这里可以看到,有了Imethod和MethodObject,在java里使用闭包,就可以像javascript那样方便了。当然,这只是模拟,如果想要达到javascript那样在运行期改变对象的属性和方法,可以在更高一级去模拟。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |