我对 Java FX 和非常奇怪的应用程序的实现有一个问题。让我用代码来展示一下:
想象一个基本应用程序:
import javafx.application.Application;
import javafx.stage.Stage;
public class JavaFXApp extends Application {
// constructor, ...
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
// important stuff
initialize();
// important stuff
stage.show();
}
public void initialize() {
System.out.println("default");
// basically abstract
}
// and other functions.
}
及其扩展(按预期):
public class JavaFXAppExtended extends JavaFXApp {
// constructor, ...
@Override
public void initialize() {
System.out.println("extended");
}
}
现在
JavaFXApp
的召唤对我来说没有任何问题。但是当调用JavaFXAppExtended
时,@Overwrite
基本上是被忽略,而来自父类的initialize
被调用。从而:
JavaFXApp.main(args);
-> default
JavaFXAppExtended.main(args);
-> default
其中“扩展”是预期的。
为什么调用来自initialize
父级的
JavaFXAppExtended
而不是
@Overwrite
? 我错过了什么重要的事情吗?这违法吗?是我经验不够吗?这可能只是一个错误?我不知道。但我想知道。
JavaFXAppExtended.main(args)
调用静态
JavaFXApp.main
,因为 JavaFXAppExtended 中没有
main
。
JavaFXAppExtended
的调用代码中没有留下任何痕迹。与
JavaFXApp.main(args)
完全相同的代码。静态函数中没有继承的
this
。因此`JavaFXApp.launch被调用。
Joop Eggen 的回答是正确的,但我只是想添加更多信息。
当 JavaFX 应用程序类和主类相同时, 方法是launch(Class,String...)
的便捷重载。类参数隐式是“调用者类”。调用者类是声明调用者方法的类。在你的问题中,调用者类是 JavaFXApp
,因为这是声明 main
的地方,并且它来自
main
,你称之为
launch
。
JavaFX 框架获取应用程序类并为您实例化它。然后,它根据documented JavaFX 应用程序生命周期调用
init
、
start
和
stop
方法。因此,在您的问题中,调用
start
方法的对象是 JavaFXApp
的实例,而不是
JavaFXAppExtended
。换句话说,
initialize
覆盖不会被忽略,而是您在与您预期不同的对象上调用
initialize
。
如果您希望
JavaFXAppExtended
成为应用程序类,那么您有两个选择:使用
launch(Class,String...)
JavaFXAppExtended.class
。从
launch(String..)
JavaFXAppExtended
(这是您选择的解决方案)。 注意,在一个项目中有两个
Application
JavaFXApp
应该是抽象的,并且
not包含
main
方法。或者,如果哪个类用作应用程序类是由某些运行时条件决定的,那么最好将该选择提取到不同的主类中。例如:
import javafx.application.Application;
public class Main {
// With this approach, neither application class should have a main method.
public static void main(String[] args) {
if (/* some condition */) {
Application.launch(JavaFXAppExtended.class, args);
} else {
Application.launch(JavaFXApp.class, args);
}
}
}