java 函数参数指针_Java中的函数指针

类似于函数指针function的Java成语是一个实现接口的匿名类,例如

Collections.sort(list, new Comparator(){ public int compare(MyClass a, MyClass b) { // compare objects } });

更新:在Java 8之前的Java版本中,上述是必需的。现在我们有更好的select,即lambda:

list.sort((a, b) -> a.isGreaterThan(b));

和方法参考:

list.sort(MyClass::isGreaterThan);

你可以用一个接口取代一个函数指针。 比方说,你想通过一个集合运行,并与每个元素做一些事情。

public interface IFunction { public void execute(Object o); }

这是我们可以传递给一些说CollectionUtils2.doFunc(集合c,IFunction f)的接口。

public static void doFunc(Collection c, IFunction f) { for (Object o : c) { f.execute(o); } }

举一个例子说,我们有一个数字的集合,你想为每个元素加1。

CollectionUtils2.doFunc(List numbers, new IFunction() { public void execute(Object o) { Integer anInt = (Integer) o; anInt++; } });

你可以使用reflection来做到这一点。

作为parameter passing对象和方法名称(作为string),然后调用该方法。 例如:

Object methodCaller(Object theObject, String methodName) { return theObject.getClass().getMethod(methodName).invoke(theObject); // Catch the exceptions }

然后使用它在:

String theDescription = methodCaller(object1, "toString"); Class theClass = methodCaller(object2, "getClass");

当然,检查所有exception并添加所需的强制转换。

对不起,我的英文不好。

再见!

不,函数不是java中的头等对象。 你可以通过实现一个处理器类来做同样的事情 – 这就是在Swing中如何实现callback。

然而,在未来的Java版本中有closures的build议(你正在谈论的正式名称) – Javaworld有一篇有趣的文章。

这让人想起史蒂夫·叶格的“名词王国的执行” 。 它基本上规定Java需要每个动作的对象,因此不具有像动词指针这样的“只动”实体。

要实现类似的function,你可以使用匿名的内部类。

如果你要定义一个接口Foo :

interface Foo { Object myFunc(Object arg); }

创build一个方法bar ,它将接收一个“函数指针”作为参数:

public void bar(Foo foo) { // ..... Object object = foo.myFunc(argValue); // ..... }

最后调用方法如下:

bar(new Foo() { public Object myFunc(Object arg) { // Function code. } }

Java中没有这样的东西。 您将需要将您的函数包装到某个对象中,并将引用传递给该对象,以便将该引用传递给该对象上的方法。

在语法上,这可以通过使用定义在位的匿名类或定义为类的成员variables的匿名类来在一定程度上得到缓解。

例:

class MyComponent extends JPanel { private JButton button; public MyComponent() { button = new JButton("click me"); button.addActionListener(buttonAction); add(button); } private ActionListener buttonAction = new ActionListener() { public void actionPerformed(ActionEvent e) { // handle the event... // note how the handler instance can access // members of the surrounding class button.setText("you clicked me"); } } }

我已经使用reflection在Java中实现了callback/委托支持。 细节和工作来源可以在我的网站上find 。

怎么运行的

我们有一个名为Callback的原型类,它带有一个名为WithParms的嵌套类。 需要callback的API将一个Callback对象作为参数,如果需要的话,创build一个Callback.WithParms作为方法variables。 由于这个对象的很多应用都是recursion的,所以这个工作非常干净。

性能仍然是我的首要任务,我不希望被要求创build一个一次性的对象数组来保存每个调用的参数 – 毕竟在一个大型的数据结构中可能有成千上万的元素,并在一个消息处理我们最终可能会每秒处理数千个数据结构。

为了成为线程安全的参数数组需要唯一地存在于API方法的每个调用中,并且为了效率,每次调用callback都应该使用同一个参数; 我需要第二个对象,这将创build便宜,以便绑定与调用参数数组的callback。 但是,在某些情况下,由于其他原因,调用者将已经拥有参数数组。 由于这两个原因,参数数组不属于callback对象。 同样,select调用(将参数作为数组或单独对象传递)属于API的手中,使用callback使它能够使用最适合其内部工作的调用。

WithParms嵌套类是可选的,它有两个目的,它包含callback调用所需的参数对象数组,它提供了10个重载的invoke()方法(有1到10个参数),它们加载参数数组,然后调用callback目标。

Java8引入了lambdas和方法引用 。 所以如果你的函数匹配一个函数接口 (你可以创build你自己的),你可以在这种情况下使用方法引用。

Java提供了一组通用的function接口 。 而您可以执行以下操作:

public class Test { public void test1(Integer i) {} public void test2(Integer i) {} public void consumer(Consumer a) { a.accept(10); } public void provideConsumer() { consumer(this::test1); // method reference consumer(x -> test2(x)); // lambda } }

检查closures是如何在lambdaj库中实现的。 他们实际上有一个非常类似于C#代表的行为:

相对于大多数人来说,我是新来的Java,但因为我没有看到类似的build议,我有另一种selectbuild议。 林不知道是否是一个好的做法,甚至以前build议,我只是没有得到它。 我只是喜欢它,因为我认为它的自我描述。

/*Just to merge functions in a common name*/ public class CustomFunction{ public CustomFunction(){} } /*Actual functions*/ public class Function1 extends CustomFunction{ public Function1(){} public void execute(){...something here...} } public class Function2 extends CustomFunction{ public Function2(){} public void execute(){...something here...} } ..... /*in Main class*/ CustomFunction functionpointer = null;

然后根据应用程序,分配

functionpointer = new Function1(); functionpointer = new Function2();

等等

并通过

functionpointer.execute();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值