声明 类 导致 StackOverflow 错误

Declaring Classes causes StackOverflow error

我四处寻找答案,我看到的最接近我的问题的是:Object creation causes runtime error 就像我的一样抛出 java.lang.WhosebugError。它指的是我将 类 初始化为对象的行,我认为它不应该循环。这是错误:

Exception in Application start method
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 com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
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: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication4(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.WhosebugError
at sample.Script.<init>(Script.java:9)
at sample.Controller.<init>(Controller.java:34)
at sample.Script.<init>(Script.java:9)
at sample.Controller.<init>(Controller.java:34)
at sample.Script.<init>(Script.java:9)
at sample.Controller.<init>(Controller.java:34)
at sample.Script.<init>(Script.java:9)
at sample.Controller.<init>(Controller.java:34)
at sample.Script.<init>(Script.java:9)

这是第 34 行之前的控制器:

package sample;

import javax.swing.*;
import javafx.fxml.FXML;
import java.util.Arrays;
import javafx.geometry.Insets;
import javafx.scene.layout.VBox;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.control.TextField;
import javafx.scene.control.ScrollPane;

public class Controller {

    private String msg;
    private char[] msgA;
    @FXML
    private Label opt1;
    @FXML
    private Label opt2;
    @FXML
    private Label opt3;
    @FXML
    private TextField msgBox;
    @FXML
    private AnchorPane optPane;
    @FXML
    private AnchorPane gameUI;
    @FXML
    private AnchorPane mainMenu;
    @FXML
    private ScrollPane labelPane;
    private final Script script = new Script(); //Line 34 <--
    ....
}

这是第 9 行之前的脚本:

package sample;

import java.util.ArrayList;

class Script {

    /*Variables*/
    public final ArrayList choice = new ArrayList();
    private final Controller c = new Controller();//Line 9! <--
    ....
}

是不是因为我在 类 中都创建了对象?我应该扩展控制器吗?

public class Controller {
    private final Script script = new Script();
    ...
}

Controller 的每个实例都会创建一个新的 Script 实例。

public class Script {
    private final Controller c = new Controller();
    ...
}

每个 Script 实例都会创建一个新的 Controller 实例。

这意味着实例化 class 会让您陷入循环:假设您创建了一个新的 Script 实例,假设堆栈跟踪看起来像这样:

  1. 在脚本初始化期间,创建了一个控制器实例。
  2. 在Controller的初始化过程中,创建了一个Script实例。
  3. 在脚本初始化期间,创建了一个控制器实例。
  4. 在Controller初始化期间,创建了一个Script实例。

等等。

您要实现的是相互 class 引用。 Controller 持有对 Script 的引用,而 Script 持有对 Controller 的引用。不管这在这种情况下是否合适,实现这一点的一种方法是将对 Controller 的引用传递给 Script 的构造函数。

public class Controller {
    private final Script script;
    public Controller() {
        script = new Script(this);
    }
    public Script getScript() { 
        return script; 
    }
    ...
}

public class Script {
    private final Controller controller;
    public Script(Controller c) {
        controller = c;
    }
    ...
}