Mr.*_*ear 8 java javafx javafx-8
可以说,我们有以下课程:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
它源自Application但不使用任何方法.通常通过launch(args)在main中调用来启动JavaFX应用程序.
当我启动这个程序时,唯一的输出是"main",因此不会调用构造函数和start,但程序不会因为运行JavaFX Application线程而终止.但是它来自哪里?
我做了一些调试,发现在main方法运行之前,线程是从主线程启动的.堆栈跟踪以NativeMethodAccessorImpl.
为了更加奇怪:当我从另一个类启动main方法时,JavaFX Application线程没有启动:
public class Test2
{
public static void main(String[] args)
{
Test.main(args);
}
}
Run Code Online (Sandbox Code Playgroud)
那么这是什么样的黑魔法呢?
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());
}
}
Run Code Online (Sandbox Code Playgroud)
输出是
您可以看到该类的实际加载的主类Test2是Test2,但是加载的主类
Test是sun.launcher.LauncherHelper$FXHelper.
发生这种情况是因为Java启动程序检查要启动的主类是否是其子类javafx.application.Application.如果是,则加载main方法sun.launcher.LauncherHelper$FXHelper,它调用JavaFX应用程序的启动器方法(com.sun.javafx.application.LauncherImpl#launchApplication).
此方法负责启动JavaFX应用程序.Test#main在应用程序启动后调用:

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