JavaFX 8如何在几乎空的Application类中启动JavaFX Application线程?

可以说,我们有以下课程:

import javafx.application.Application; import javafx.stage.Stage; public class Test extends Application { public Test() { System.out.println("Constructor"); } @Override public void start(Stage primaryStage) throws Exception { System.out.println("start"); } public static void main(String... args) { System.out.println("main"); } } 

它源自Application但它不使用任何方法。 通常通过在main中调用launch(args)来启动JavaFX应用程序。

当我启动这个程序时,唯一的输出是“main”,因此不会调用构造函数和start,但程序不会因为运行JavaFX Application线程而终止。 但它来自哪里?

我做了一些调试,发现在main方法运行之前,线程是从主线程启动的。 堆栈跟踪以NativeMethodAccessorImpl开头。

为了更加奇怪:当我从另一个类启动main方法时,JavaFX Application线程没有启动:

 public class Test2 { public static void main(String[] args) { Test.main(args); } } 

那么这是什么样的黑魔法呢?

Java使用不同的方法来启动这两个应用程序。

尝试运行以下代码:

 public class Test3 { public static void main(String[] args) { Class actualMainClassTest = LauncherHelper.checkAndLoadMain(true, 1, Test.class.getName()); Class actualMainClassTest2 = LauncherHelper.checkAndLoadMain(true, 1, Test2.class.getName()); System.out.println("Actual loaded main class for Test: " + actualMainClassTest.getName()); System.out.println("Actual loaded main class for Test2: " + actualMainClassTest2.getName()); } } 

输出是

  • Test的实际加载主类:sun.launcher.LauncherHelper $ FXHelper
  • Test2的实际加载主类:Test2

您可以看到Test2类的实际加载主类是Test2 ,但Test的加载主类是sun.launcher.LauncherHelper$FXHelper

发生这种情况是因为Java启动程序检查要启动的主类是否是javafx.application.Application的子类。 如果是,则加载sun.launcher.LauncherHelper$FXHelper的main方法,它调用JavaFX应用程序的启动器方法( com.sun.javafx.application.LauncherImpl#launchApplication )。

此方法负责启动JavaFX应用程序。 在启动应用程序后调用Test#main

在此处输入图像描述

当Test2调用Test#main ,不使用FX启动器,因为Test2不是javafx.application.Application的子类。