gpt4 book ai didi

java - 静态初始化程序中的异常处理

转载 作者:行者123 更新时间:2023-12-01 17:45:10 26 4
gpt4 key购买 nike

通常,我通过显示一些带有详细信息的自定义警报 (JavaFX) 来处理异常,但当我的类的静态初始化程序运行时,JavaFX 运行时根本不会初始化。

有没有办法处理这种异常,而不需要像动物一样打印其内容来输出?

public class MyStaticInitializedClass {

static {
try {
//do the things that may throw exception
} catch(Exception ex) {
ExceptionHandler.showException(ex);
}
}

}

public class ExceptionHandler {

public static void showException(Exception ex) {
//constructs JavaFX alert with exception details
alert.show();
}

}

最佳答案

首先考虑是否不应该让应用程序崩溃并记录原因。静态初始化程序中的失败通常意味着环境存在严重错误,您不太可能从中恢复。另外,据我所知,一旦类加载失败,它就无法再次被同一个 ClassLoader 加载。

也就是说,如果您想在警报中向用户显示错误,即使错误发生在 JavaFX 运行时初始化之前,您也需要将错误保存在某处。然后,启动 JavaFX 后,检查存储错误的位置并显示它们。例如:

Main.java:

import javafx.application.Application;

public class Main {

public static void main(String[] args) {
// an "error" before JavaFX is launched
App.notifyUserOfError(new RuntimeException("OOPS!"));
Application.launch(App.class, args);
}
}

应用程序.java:

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayDeque;
import java.util.Objects;
import java.util.Queue;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;

public class App extends Application {

private static Queue<Throwable> errorQueue;
private static App appInstance;

public static synchronized void notifyUserOfError(Throwable throwable) {
Objects.requireNonNull(throwable);
if (appInstance == null) {
if (errorQueue == null) {
errorQueue = new ArrayDeque<>();
}
errorQueue.add(throwable);
} else {
if (Platform.isFxApplicationThread()) {
appInstance.showErrorAlert(throwable);
} else {
Platform.runLater(() -> appInstance.showErrorAlert(throwable));
}
}
}

private static synchronized Queue<Throwable> setAppInstance(App instance) {
if (appInstance != null) {
throw new IllegalStateException();
}
appInstance = instance;

var queue = errorQueue;
errorQueue = null; // no longer needed
return queue;
}

private Stage primaryStage;

@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;

var scene = new Scene(new StackPane(new Label("Hello, World!")), 600, 400);
primaryStage.setScene(scene);
primaryStage.show();

var errors = setAppInstance(this);
if (errors != null) {
// if non-null then should be non-empty
do {
showErrorAlert(errors.remove());
} while (!errors.isEmpty());
// possibly exit the application if you can't recover
}
}

private void showErrorAlert(Throwable error) {
var alert = new Alert(AlertType.ERROR);
alert.initOwner(primaryStage);
alert.setContentText(error.toString());

var sw = new StringWriter();
error.printStackTrace(new PrintWriter(sw));

var area = new TextArea(sw.toString());
area.setEditable(false);
area.setFont(Font.font("Monospaced", 12));

var details = new VBox(5, new Label("Stack trace:"), area);
VBox.setVgrow(area, Priority.ALWAYS);
alert.getDialogPane().setExpandableContent(details);

alert.showAndWait();
}
}

如果 JavaFX 尚未初始化,上面的代码会将错误放入队列中。在 start 方法结束时,将检查队列是否有任何错误,并将它们一个接一个地显示给用户。如果 JavaFX 已经初始化,则错误会立即显示给用户。

关于java - 静态初始化程序中的异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60876464/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com