如何在Java中将可执行块作为参数传递?

32

有没有一种方法可以将可执行的代码块作为参数传递给静态方法?这是否可能?例如,我有这个方法

public static void someMethod(boolean flag, Block block1, BLock block2) {
    //some other code
    if(flag)
        block1.execute();
    else block2.execute();
    //some other code
}

或类似的东西。实际上比这更复杂,我只是简化了问题。我正在尝试重构我的项目,并创建了一个通用的实用类,其中包含我的类使用的静态方法。


4
了解命令模式。 - Sotirios Delimanolis
我认为下一个版本的Java有类似的功能,但现在还没有语言支持,你必须将逻辑封装在类中,就像在Swing应用程序中处理事件一样。 - zneak
7
请使用Runnable、Future或您选择的接口。 - Hovercraft Full Of Eels
3
在将您的代码重构为静态方法之前,您可能希望阅读这篇文章。http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/。 - Dawood ibn Kareem
2
Java 8 增加了对lambda表达式的支持,可以与像 RunnableCallable 这样的单方法接口结合使用,使得传递“代码块”的语法非常简洁。 - DaoWen
显示剩余3条评论
2个回答

44

你可以使用 Runnable 对象:

public static void someMethod(boolean flag, Runnable block1, Runnable block2) {
    //some other code
    if(flag)
        block1.run();
    else block2.run();
    //some other code
}

然后你可以这样调用它:

Runnable r1 = new Runnable() {
    @Override
    public void run() {
        . . .
    }
};
Runnable r2 = . . .
someMethod(flag, r1, r2);

编辑(抱歉,@Bohemian):在Java 8中,使用lambda表达式可以简化调用代码:

someMethod(flag, () -> { /* block 1 */ }, () -> { /* block 2 */ });

您仍然可以以相同的方式声明someMethod。 lambda语法只是简化了创建和传递Runnable的方式。


如果从工作线程调用.run(),那么run方法中的代码也会在工作线程上执行吗?如何在主线程上执行呢? - János
1
@János - 要在主线程上运行,您必须使用“Handler”并将“Runnable”发布到其中,以便由处理程序而不是工作线程代码运行。 - Ted Hopp

0
你可以简单地创建一个接口,并从实现该接口的类中传递对象。这被称为命令模式。
例如,你可以有:
public interface IBlock
{
   void execute();
}

还有一个实现类:

public class Block implements IBlock
{
    public void execute()
    {
        // do something
    }
}

在Java 8中,您将能够传递lambda表达式,例如谓词和函数,这将使代码更加简洁,但本质上执行相同的操作。

8
没必要发明新的接口来完成这个任务,可以使用Runnable - Stephen C
使用Runnable听起来并不干净,这只是我的观点,从未见过代码以那种方式使用Runnable。 - Seb
1
@Seb - 有什么不干净的地方吗?Runnable就是为这种情况而设计的:传递一个“代码块”,可以在以后(在另一个线程上;在将来的某个时间;当满足某些条件时等)执行它。 - Ted Hopp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接