首页 > 解决方案 > 当通过反射调用 main 时,JVM 以可见的窗口退出

问题描述

Mac OS X 卡特琳娜

JDK OpenJDK 14.0.2(同一问题 14.0.1)

public class PriceUpdateForm extends JPanel {
/* lots of code omitted */
   public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> startGUI());
        /* try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            System.exit(17);
        } */
    }

    private static void startGUI() {
        final var form = new PriceUpdateForm();
        form.j = new JFrame();
        form.j.getContentPane().add(form);
        form.j.pack();
        form.j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        form.j.setVisible(true);
    }
}

main当直接从命令行(或 IntelliJ)调用此类的方法时,即使注释掉了 sleep,它也会按预期工作。该窗口一直可见,直到您单击关闭按钮,然后程序退出。

相反,当我使用蹦床模式时,其中类名是第一个参数,如下所示,即使窗口可见,JVM 也愿意退出。当窗口立即消失时,我很难调试这个,但如果你取消注释睡眠,JVM 将在 3 秒后退出,直到那时窗口清晰可见。

蹦床的主要方法节选

            final Class<?> mainClass = Class.forName(args[0]);
            final Method mainMethod = mainClass.getDeclaredMethod("main", newArgs.getClass());
            mainMethod.invoke(null, new Object[]{newArgs});

newargs只是原始参数减去第零个。

我在没有睡眠的情况下得到了它,PriceUpdateForm.main它将退出,但我不明白为什么它会随着它一起关闭窗口。这是在 GUI 线程上创建的。它不会超出范围,或者至少,无论如何main调用它的范围都应该是相同的:直接或通过反射。

有人可以解释这种行为差异吗?我想我可以做一个长达数年的sleep,但这看起来很难看。

标签: javaswingjvmswingworker

解决方案


推荐阅读