How does JavaFX 8 start the JavaFX Application thread in a nearly empty Application class?

戏子无情 提交于 2020-01-01 04:54:12

问题


Lets say, we have the following class:

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");
    }
}

It's derived from Application but it doesn't use any of its methods. Usually you start a JavaFX application by calling launch(args) in the main.

When I start this program the only output is "main", so the constructor and start aren't called, but the program doesn't terminate because there is a JavaFX Application thread running. But where does it come from?

I did some debugging and found out that the thread is started from the main thread before the main method runs. The stack trace starts with NativeMethodAccessorImpl.

To get even weirder: when I start the main method from a different class, the JavaFX Application thread isn't started:

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

So what kind of black magic is this?


回答1:


Java uses different approaches to launch the two applications.

Try running the following code:

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());
    }
}

The output is

  • Actual loaded main class for Test: sun.launcher.LauncherHelper$FXHelper
  • Actual loaded main class for Test2: Test2

You can see that the actual loaded main class for the Test2 class is Test2, but the loaded main class for Test is sun.launcher.LauncherHelper$FXHelper.

This happens because the Java launcher checks if the main class to be launched is a subclass of javafx.application.Application. If it is, it loads the main method of sun.launcher.LauncherHelper$FXHelper instead, which invokes a launcher method for JavaFX applications (com.sun.javafx.application.LauncherImpl#launchApplication).

This method is responsible for launching the JavaFX application. Test#main is called after the application is launched:

When Test#main is called by Test2, the FX launcher is not used because Test2 is not a subclass of javafx.application.Application.



来源:https://stackoverflow.com/questions/28321369/how-does-javafx-8-start-the-javafx-application-thread-in-a-nearly-empty-applicat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!