可以说,我们有以下课程:
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);
}
}
这是什么样的黑魔法?
答案 0 :(得分:5)
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());
}
}
输出
您可以看到Test2
类的实际加载主类是Test2
,但加载的主类是
Test
为sun.launcher.LauncherHelper$FXHelper
。
这是因为Java启动程序检查要启动的主类是否是javafx.application.Application
的子类。
如果是,则加载sun.launcher.LauncherHelper$FXHelper
的主方法,而不是调用启动器方法
对于JavaFX应用程序(com.sun.javafx.application.LauncherImpl#launchApplication
)。
此方法负责启动JavaFX应用程序。启动应用程序后调用Test#main
:
当Test2调用Test#main
时,不会使用FX启动器,因为Test2不是javafx.application.Application
的子类。