class A {
public static void methodToPass(int i) {
// do stuff
}
}
import java.util.function.IntConsumer;
class B {
public void dansMethod(int i, IntConsumer aMethod) {
/* you can now call the passed method by saying aMethod.accept(i), and it
will be the equivalent of saying A.methodToPass(i) */
}
}
class C {
B b = new B();
public C() {
b.dansMethod(100, j -> A.methodToPass(j)); //Lambda Expression here
}
}
public class Demo {
public Demo(/.../){
}
public void view(Action a){
a.preform();
}
/**
* The Action Class is for making the Demo
* View Custom Code
*/
public abstract class Action {
public Action(/.../){
}
abstract void preform();
}
}
现在你可以做类似的事情从类中调用一个方法 .
/...
Demo d = new Demo;
Action a = new Action() {
@Override
void preform() {
//Custom Method Code Goes Here
}
};
/.../
d.view(a)
8 回答
我使用了@jk的命令模式 . 提到,添加一个返回类型:
Java(尚未)支持闭包 . 但是还有其他语言,如Scala和Groovy,它们在JVM中运行并支持闭包 .
Java 8及以上版本
使用Java 8 lambda表达式,如果您的类或接口只有一个方法,例如:
然后在任何使用MyInterface的地方,您可以替换lambda表达式:
例如,您可以非常快速地创建新线程:
并使用method reference syntax使其更清洁:
如果没有lambda表达式,最后两个示例将如下所示:
在Java 8之前
一个常见的模式是在界面内'wrap',例如
Callable
,然后你传入一个Callable:这种模式称为Command Pattern .
请记住,最好为特定用途创建界面 . 如果您选择使用callable,那么您将使用您期望的任何类型的返回值替换上面的T,例如String .
根据您的评论,您可以说:
然后调用它,也许使用匿名内部类:
请记住,这不是一个“技巧” . 它只是java的基本概念等价于函数指针 .
您可以使用Java反射来执行此操作 . 该方法将表示为java.lang.reflect.Method的实例 .
Lambda表达式
要添加到jk.'s excellent answer,您现在可以使用Lambda Expressions(在Java 8中)更轻松地传递方法 . 首先,一些背景 . 功能接口是一个只有一个抽象方法的接口,尽管它可以包含任意数量的default methods(Java 8中的新增功能)和静态方法 . 如果不使用lambda表达式,lambda表达式可以快速实现抽象方法,而不需要所有不必要的语法 .
没有lambda表达式:
使用lambda表达式:
以下是the Java tutorial on Lambda Expressions的摘录:
以下是使用lambda表达式“传递方法”的方法:
注意:这使用新的标准功能接口java.util.function.IntConsumer .
使用:: operator可以进一步缩短上面的示例 .
感谢Java 8,你不要使用lambdas,请参阅Oracle's Lambda Expression tutorial . 本文的其余部分描述了我们过去在过去的糟糕时期必须要做的事情,以实现此功能 .
通常,您将方法声明为使用单个方法接受某个接口,然后传入实现该接口的对象 . 一个例子是在commons-collections中,你有Closure,Transformer和Predicate的接口,以及你将它们的实现传递到的方法 . Guava是新改进的commons-collections,你可以在那里找到相应的接口 .
例如,commons-collections有org.apache.commons.collections.CollectionUtils,它有许多静态方法接受传入的对象,随机选择一个,这个签名存在一个名为exists的存在:
它需要一个实现接口Predicate的对象,这意味着它必须有一个方法,它接受一些Object并返回一个布尔值 .
所以我可以这样称呼它:
它返回true或false,具体取决于
someCollection
是否包含谓词返回true的对象 .无论如何,这只是一个例子,公共收藏已经过时了 . 我忘记了 Guava 中的等价物 .
Java支持闭包就好了 . 它只是不支持函数,所以你习惯用于闭包的语法更加笨拙和笨重:你必须用一个方法将所有东西都包装在一个类中 . 例如,
将返回一个传入的
run()
方法"closes over"的Runnable对象,就像支持第一类函数和闭包的任何语言一样 .我知道这是一个相当古老的帖子,但我有另一个稍微简单的解决方案 . 您可以在其中创建另一个类并使其成为抽象类 . 接下来,使用任何您喜欢的方法将Abstract方法命名为 . 在原始类中创建一个以新类作为参数的方法,在此方法中调用抽象方法 . 它看起来像这样 .
现在你可以做类似的事情从类中调用一个方法 .
就像我说的那样,我知道它已经老了,但这种方式我觉得有点容易 . 希望能帮助到你 .