Java中与C#委托类似的功能(排队执行各种类的方法)

14

简介:

是否有 Java 中类似于 C# 的委托(delegates)的结构来允许我动态地将各个类的方法添加到队列中?希望使用语言结构而不是代码来实现。

背景:

我之前使用过 Unity 3D,并且喜欢脚本中的 Update 方法。只需声明该方法即可将其添加到每帧执行的方法列表中。我想在我的 LWJGL 游戏中创建类似的东西。为此,我想使用委托(或类似委托的结构)。是否有任何 Java 语言结构可以让我这样做?我更喜欢包含两种或更多结构的答案(以便我可以选择哪种对我的代码最优),以及使用它们的方法。我不想要代码,只想知道从哪里开始。编程最有趣的部分是解决问题,我不想被剥夺这种体验。另外,我不想被告诉如何完全实现它。我希望被引导到正确的方向,而不是被直接推向那个方向和目的地。我该如何学习呢?:-)


库safety-mirror为Java添加了委托和事件。请参阅https://stackoverflow.com/a/63777276/6095334,或者更好地查看该项目的README:https://github.com/Hervian/safety-mirror。 - Hervian
3个回答

29

实际上,在Java中没有与委托完全对应的东西。但是有一些构造可以模仿它们的行为。

Java 8

函数式接口

在Java 8中,最接近委托的概念是函数式接口

例如,如果您有一个C#委托:

delegate void Runnable();

在Java中,您可以创建一个函数式接口,例如:
@FunctionalInterface
public interface Runnable {
    void run();
}

函数式接口的好处在于它们可以很容易地在lambda表达式中使用。

示例

假设您有以下类:

public class SomeClass {
    public static void someStaticMethod() {
    }

    public void someMethod() {
    }
}

Lambda表达式和方法引用

在Java 8中,您可以使用Lambda表达式。

List<Runnable> queue = new ArrayList<>();
queue.add(() -> someMethod());
queue.add(() -> someStaticMethod());

如果您实际上只是调用一个方法,那么有一个名为方法引用的简写方式:

List<Runnable> queue = new ArrayList<>();
queue.add(this::someMethod);
queue.add(SomeClass::someStaticMethod);

Java 7

Java 7 中,你唯一能使用的是匿名类

List<Runnable> queue = new ArrayList<>();
queue.add(new Runnable() {
    public void run() {
        someMethod();
    }
});
queue.add(new Runnable() {
    public void run() {
        someStaticMethod();
    }
});

希望这些信息不会太多,这样你仍然可以学到。;-) 但是,我希望我的回答也对其他查找此问题的人有用。


2
回顾一年多后,我仍然从这个答案中学到了很多东西,因为我现在更理解它,并且质疑我当初提问的方式(请求少量信息来重新发明轮子)。特别是方法引用部分是一个有趣的功能,因为它让我想起了C(++)命名空间成员访问。你应该得到一个早就该有的赞 :) - James Yeoman
@JamesYeoMan:谢谢你的回复 :-)实际上,StackOverflow是提供好的和高质量答案的地方,而不是提供“提示”的地方 ;-)C++的东西可能只是巧合...他们只是需要在Java中为_method_references_提供语法,并选择了那个。 - Michaela Elschner

10

源自https://msdn.microsoft.com/en-gb/library/aa288459(v=vs.71).aspx

C#中的委托类似于C或C ++中的函数指针。使用委托允许程序员将对方法的引用封装在委托对象中。然后可以将委托对象传递给调用引用方法的代码,而无需在编译时知道将调用哪个方法。与C或C++中的函数指针不同,委托是面向对象、类型安全和安全的。

话虽如此,Java没有像C#一样的委托。 但是,自Java 8以来,我们可以通过使用方法引用和函数接口来实现某种形式的函数指针。

正如您所请求的那样,我不会告诉您确切的代码实现方式,但是您应该能够根据这些信息想出一个解决方案。


这个回答把我的请求推向了极端,但并没有给我所需的代码... 这很好。然而,对于未来类似的问题的改进是不要假设我知道像接口和其他中高级技能一样的东西,因为现在我必须去研究关于接口等内容的知识。这只是对你未来答案的建议。顺便说一句,谢谢。 - James Yeoman
1
谢谢您的反馈!我会在下次考虑到它。 - Jose Ignacio Acin Pozo

1

Java函数接口!=C#委托。从消费者的角度来看,除了一个纯C风格的函数指针之外,您将无法获得任何详细信息。您无法确定Java函数接口是否绑定了一些对象作为lambda表达式或成员函数,还是只是一个没有依赖关系的静态方法。我想说,C#委托提供了一些非常有趣的功能,可能不那么重要,可以帮助诊断潜在的程序缺陷,比如委托的线程安全性。


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