【问题标题】:why class of main method should be public in javafx?为什么 main 方法的类应该在 javafx 中公开?
【发布时间】:2016-07-17 13:03:40
【问题描述】:

这里是用于 JavaFX 项目的 netbeans IDE 的模板代码。 如果你从 BombDroid 类中清除 public 关键字,你会得到运行时错误。为什么? 注意:我知道 main 应该是公开的。但是为什么 Bombdroid 类应该是公开的呢?

package bombdroid;

import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.shape.*;
import javafx.stage.Stage;

public class BombDroid extends Application {
    @Override
    public void start(Stage primaryStage) {
        Group root = new Group();
        Scene scene = new Scene(root);
        Line line = new Line(0, 0, 500, 500);
        Rectangle man = new Rectangle(0, 0, 100, 100);
        root.getChildren().add(line);
        root.getChildren().add(man);
        primaryStage.setScene(scene);
        primaryStage.show();
        }
    public static void main(String[] args) {
        launch(args);
        }
    }

【问题讨论】:

  • 我的猜测是,因为最终调用 main 的是不同的类,所以这些类看不到那个类,因为它是 defaultpackage-private。我很想看看如果您将包设置为与调用代码相同会发生什么(java.lang 也许?)
  • @Zymus,这是由 JRE 运行时启动器java 启动的应用程序。没有充当调用代码的用户代码。所有调用代码都在 JRE 中。由于 JRE 安全限制,用户代码不能放在 java.lang (java.lang.SecurityException: Prohibited package name: java.lang) 中,因此无法尝试您建议的测试。
  • 虽然可能会认为这个问题是相关问题的重复:why main method in Java need to be public always?,但这并不是因为这个问题是指包含 main 方法的类上的访问分类器,而不是main 方法本身。

标签: java javafx


【解决方案1】:

JavaFX 应用程序的启动器通过反射工作,其结果和使用方式是必须将 JavaFX 应用程序类声明为公共的。

您在运行示例时收到的具体错误消息(没有 main 方法,这对于 JavaFX 应用程序来说是不必要的)是:

Exception in Application constructor
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class BombDroid
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodException: BombDroid.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.getConstructor(Class.java:1825)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:818)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

如您所见,系统正在为您的应用程序类寻找无参数构造函数。追根溯源,LauncherImpl.java:818处的源码是:

Constructor<? extends Application> c = appClass.getConstructor();

getConstructor() 方法的文档指出:

返回一个Constructor 对象,该对象反映了此Class 对象所表示的类的指定公共构造函数。

如果没有找到匹配的方法,@throws NoSuchMethodException。

如果您的应用程序类不是公共的,则它没有公共构造函数,并且当您尝试启动它时会返回 NoSuchMethodException。这就是这里发生的情况,导致应用程序启动失败。

一边

请注意,JavaFX 的应用程序类公开的要求不同于非 JavaFX 应用程序。例如,Java 中最简单的 hello world 程序不需要公共类即可运行,只需要公共 main 方法即可。

class HelloWorld {
    public static void main(String[] args) {
        System.out.println("hello, world");
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-23
    • 2018-11-16
    • 1970-01-01
    • 2013-08-28
    • 2012-02-25
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    相关资源
    最近更新 更多