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
的子类。