2015-02-04 3 views
8

Diciamo, abbiamo la seguente classe:In che modo JavaFX 8 avvia il thread JavaFX Application in una classe Application quasi vuota?

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

E 'derivato da Application ma non usa nessuno dei suoi metodi. Solitamente si avvia un'applicazione JavaFX chiamando lo launch(args) nel main.

Quando avvio questo programma, l'unico output è "main", quindi il costruttore e l'avvio non vengono chiamati, ma il programma non termina perché è in esecuzione un thread JavaFX Application. Ma da dove viene?

Ho eseguito il debug e ho scoperto che il thread è stato avviato dal thread principale prima dell'esecuzione del metodo principale. La traccia dello stack inizia con NativeMethodAccessorImpl.

Per ottenere risultati ancora più strano: quando inizio il metodo principale da una classe diversa, il filo JavaFX Application non viene avviato:

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

Quindi, che tipo di magia nera è questo?

+0

Upvote per magia nera. – GGrec

+0

Nella seconda classe, Test2, non è stata aggiunta un'Applicazione nella dichiarazione della classe originale. Quindi il tuo runtime non ha alcuna idea che sia coinvolto un processo JavaFX - potrebbe essere un metodo principale (.) Di qualsiasi altro tipo di classe Java. – Trunk

risposta

5

Java utilizza approcci diversi per avviare le due applicazioni.

Provare a eseguire il seguente codice:

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

L'uscita è

  • Actual classe principale caricata per la prova: sun.launcher.LauncherHelper $ FXHelper
  • Actual classe principale caricato per Test2: Test2

Si può vedere che la classe principale attualmente caricata per lo Test2 classe è Test2, ma la classe principale caricata per Test è sun.launcher.LauncherHelper$FXHelper.

Ciò accade perché il programma di avvio Java controlla se la classe principale da avviare è una sottoclasse di javafx.application.Application. Se lo è, carica invece il metodo principale di sun.launcher.LauncherHelper$FXHelper, che richiama un metodo di avvio per applicazioni JavaFX (com.sun.javafx.application.LauncherImpl#launchApplication).

Questo metodo è responsabile dell'avvio dell'applicazione JavaFX. Test#main è chiamato dopo l'applicazione viene avviata:

enter image description here

Quando Test#main viene chiamato dal Test2, il lanciatore FX non viene utilizzato perché Test2 non è una sottoclasse di javafx.application.Application.

+0

Quindi, questo è un comportamento di java.exe e funziona solo per javafx.application.Application? – Rafaesp