Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFX运行时主方法_Java_Javafx - Fatal编程技术网

JavaFX运行时主方法

JavaFX运行时主方法,java,javafx,Java,Javafx,JavaFX的声明说: 当使用JavaFX Packager工具创建应用程序的JAR文件时,JavaFX应用程序不需要main()方法,该工具将JavaFX启动器嵌入JAR文件中。但是,包含main()方法非常有用,这样您就可以运行在没有JavaFX启动器的情况下创建的JAR文件,例如在使用未完全集成JavaFX工具的IDE时。此外,嵌入JavaFX代码的Swing应用程序需要main()方法 我尝试了这个方法,它是正确的,我可以不用main方法启动我的应用程序 但是,当我从应用程序类中声明一个

JavaFX的声明说:

当使用JavaFX Packager工具创建应用程序的JAR文件时,JavaFX应用程序不需要main()方法,该工具将JavaFX启动器嵌入JAR文件中。但是,包含main()方法非常有用,这样您就可以运行在没有JavaFX启动器的情况下创建的JAR文件,例如在使用未完全集成JavaFX工具的IDE时。此外,嵌入JavaFX代码的Swing应用程序需要main()方法

我尝试了这个方法,它是正确的,我可以不用
main
方法启动我的应用程序

但是,当我从
应用程序
类中声明一个
main
方法调用
launch
时,程序仍然有效。 的文档说,JavaFX运行时正在创建
应用程序
类的实例,并调用
init
方法


但是JavaFX运行时是如何启动的呢?我的意思是,必须有一个
main
方法才能启动一切。所以我想知道我是否自己声明了一个
main
方法,不是有两个吗?

一个可能的答案可能是,在
应用程序中声明了一个
main
方法。如果从
Application
扩展的另一个类有自己的
main
方法,则该代码仍然有效,并且
Application
main
方法将被忽略:

class Main extends OtherMain {
    public Main(String text) {
        System.out.println(text);
    }

    /* If this method is removed, the main-method is called from OtherMain */
    public static void main(String[] args) {
        new Main("Called from Main-Class");
    }
}

class OtherMain {
    public static void main(String[] args) {
        new Main("Called from Other-Main-Class");
    }
}

这有意义吗?

实际上,我一直对Java如何启动JavaFX应用程序感兴趣,所以我决定调试这个过程。在回答剩下的问题之前,先做一些事情:

  • 我用JDK-10为一个独立的桌面应用程序进行了调试。快速浏览一下JDK-11源代码,就可以看出该过程在不同版本之间没有改变
  • 当我使用
    Application
    时,我指的是
    javafx.Application.Application
  • 当我使用“
    main
    method”时,我指的是
    publicstaticvoidmain(String[]args)
    方法。类似地,“main类”指包含
    main
    方法的类
  • 源代码的所有链接都指向OpenJDK Mercurial存储库
  • 实际上,所有这些都是实施细节,可能会在不另行通知的情况下进行更改

总结 启动JavaFX应用程序时,如果主类是
应用程序的子类
,则Java启动器使用自己的内部主类。这个内部类负责初始化JavaFXToolkit。一旦工具箱初始化,就会发生以下两种情况之一

  • 应用程序
    子类具有
    main
    方法。
    • 在本例中,一些内部JavaFX代码调用
      main
      方法。现在,开发人员负责通过
      application.launch
      完成应用程序的启动
  • 应用程序
    子类没有
    main
    方法。
    • 在本例中,相同的内部JavaFX代码启动应用程序本身。第一个案例最终在与本案例相同的地方结束
  • 基本上,在
    Application
    子类中声明的任何
    main
    方法都不是“正常的”
    main
    方法。想象一下这样的行为:

    • 内部
      main
      方法充当Java应用程序的入口点,就像所有“普通”
      main
      方法一样
    • Application
      subclass'
      main
      方法作为JavaFX应用程序的可选入口点,其中JavaFX工具包已经初始化

    详细答案 首先,您并不是“覆盖”
    应用程序
    类的
    main
    方法;
    应用程序
    类没有
    main
    方法。实际上,只要应用程序声明的主类是
    application
    的子类,Java就会使用自己的主类。对于后代,可以使用以下方法之一声明主类:

    • 在命令行(文件)上指定它:
      java-cp foo.Main
    • 在命令行(模块)上指定它:
      java-p-mfoo/foo.Main
    • 在JAR清单中指定它:
      Main类:foo.Main
    • (另一种方式我忘记了?)
    台阶 这些步骤假设是一个JavaFX应用程序。如果启动一个“常规”Java应用程序,大多数情况都不会发生

    步骤1:加载主类 内部类
    LaunchHelper
    ,通过名为
    checkAndLoadMain
    的方法检查并加载主类。此方法负责根据主类的声明方式(如上所述)解析主类。一旦找到,此方法将检查主类是否是
    应用程序的子类。如果是,则主类将更改为静态内部类:
    launchelper$FXHelper
    。然后执行一些验证,并将
    返回到本机代码

    相关代码:

    步骤2:调用
    main
    方法 在发现、加载和验证主类之后,将从(我假设)本机代码调用它。由于我们讨论的是JavaFX应用程序,现在的主要类是
    launchelper$FXHelper
    。这个类的
    main
    方法做了一件简单的事情:通过反射调用内部JavaFX代码

    相关代码:

    步骤3:JavaFX预启动 步骤2调用的代码位于名为
    launchempl
    的类中;具体来说,
    启动应用程序(String,String,String[])
    方法。此方法的作用似乎与
    launchelp类似
    
    // main class
    public class Main {
    
        public static void main(String[] args) {
            Application.launch(App.class, args);
        }
    
    }
    
    // JavaFX Application class
    public class App extends Application {
    
        @Override 
        public void start(Stage primaryStage) throws Exception {
            // setup and show primaryStage
        }
    
    }