7

我很难理解这个简单的代码:

javax.swing.SwingUtilities.invokeLater(new Runnable() {
   public void run() {
      createAndShowGUI();
   }
});

谁能解释一下它是如何工作的(简单来说,因为我是新手)?这个短代码是这个大代码的一部分。

更具体地说,我有以下问题:

  1. “public void run”是否定义了一种新方法?如果是这样,为什么在另一个方法中定义它(参见“更大的代码”以供参考)?
  2. 如果“public void run”定义了一个新方法,那么定义一个只包含一行代码(createAndShowGUI)的方法的原因是什么?
  3. “invokeLater”有什么作用?这实际上是我最复杂的问题。

我想再强调一次,我是一个新手,使用“特殊”和“技术”词会产生更多问题。

如果您决定帮助我,请提前感谢您!

4

5 回答 5

11

我能给出的最短答案是:

Runnable是 Java 中的接口,表示定义run方法的类型。任何实现此接口的类都必须为run. Runnables 表示要由系统的其他部分执行的任务。 Thread是家喻户晓的Runnable

当您的代码看起来像new InterfaceName() { //implementation }时,这称为匿名类。匿名类的重点是使一次性类实现接口类型。这个类没有名字,因此我们永远不能再引用它。它只在这里使用。

在不太了解 Swing 的情况下,它看起来像SwingUtilities.invokeLater()接受 aRunnable并且......好吧,我猜它稍后会调用它(JavaDocs 中可能描述了多少稍后)。但是,您run在这里定义为另一个方法调用的原因是内部的某些代码SwingUtilities将调用runthis 上的方法Runnable;事实上,它所能知道Runnable的只是它定义了一个带有签名的方法public void run(),因为这是Runnable接口中定义的唯一方法。

好吧,我想这毕竟不是太短。

于 2010-01-30T13:31:57.567 回答
6

这是一个匿名的内部类

您正在定义三件事:

  • 一个新的班级
  • run在该类中调用的方法
  • 该类的新实例

在这个例子中,一些操作 ( createAndShowGUI()) 需要在 Swing 线程中运行。您不能在方法调用的中间“跳转”到另一个线程,因此您将一个对象(您创建的新实例)放入队列中。当 Swing 线程准备就绪时,它将从队列中删除该对象并调用您的run方法,该方法又调用createAndShowGUI. 现在一切都发生在正确的线程中。

于 2010-01-30T13:28:12.053 回答
2

虽然这就是 Swing 通常创建 GUI 的方式,但它们所做的只是告诉您“就这样做,我们稍后会解释原因”。我想他们是对的,因为细节有些复杂,对初学者没有帮助。但不管怎么说:

invokeLater启动一个稍后将运行一个Runnable类的线程。如 finnw via 所述,runnable 类是临时创建的,并且必须根据接口new Runnable { [..] }指定方法。在这种情况下,它所做的只是执行该方法。public void run()RunnablecreateAndShowGUI

于 2010-01-30T13:36:59.800 回答
1

此代码使函数 (createAndShowGUI()) 在另一个线程中被调用。如果您不知道线程是什么,最好阅读它,但无论如何,请将其视为与执行其他代码同时执行的代码。其他代码将是此 Invoke() 调用之后的行。这在图形应用程序中很常见,代码运行以更新图形,而其他代码响应用户操作。也就是说,我没有费心阅读有关 InvokeLater() 的文档,也没有写过太多的 Java。正如“LumpN”所说——“这就是 Swing 通常创建 GUI 的方式”。

更奇怪(对于新手)的事情是 invokeLater() 参数以匿名方式定义 - “在代码内”。这实际上是一件好事,因为这门课是如此简单。所有其他答案都解释了匿名的事情。

所以:1.是的。2. 你问为什么并且要求不要获得太多技术细节——但正如“yulkes”所说——因为在 Java 中你不能将方法作为参数传递,所以你必须构建这个类,像这样构建它很好. 3. 通过我第一段的总结,你可以简单地阅读文档(只是在谷歌上搜索功能名称),也可以了解“谷歌代码搜索”。

于 2010-01-30T13:51:27.877 回答
0

当您调用 invokeLater 时,您将传递给它一个 Runnable 类型实例。Runnable 是一个只声明一个方法“public void run()”的接口。在您的短代码的第 1 行中发生的事情称为“匿名内部类”-您正在创建一个 Runnable 实例,该实例仅使用一次,您甚至没有命名它。

InvokeLater 会收到你的 Runnable,里面会做类似的事情

public static void invokeLater(Runnable r) {
    // Wait for the correct time to run this
    r.run()
}

这意味着invokeLater 将决定何时调用run 方法,从而运行createAndShowGUI。

因为在 Java 中,您不能将方法作为参数传递(还),所以您不得不创建这个一次性的 Runnable 实例。

于 2010-01-30T13:32:36.733 回答