声明类会导致StackOverflow错误

时间:2018-02-17 03:40:32

标签: java class stack-overflow

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

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$launchApplication$154(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.StackOverflowError
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! <--
    ....
}

是因为我在两个类中都创建了对象吗?我应该延长控制器吗?

1 个答案:

答案 0 :(得分:1)

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

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

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

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

这意味着实例化任何一个类都会让你陷入循环:假设您创建了一个新的Script实例,想象一下堆栈跟踪看起来像这样:

  1. 在脚本初始化期间,会创建一个Controller实例。
  2. 在Controller初始化期间,会创建一个Script实例。
  3. 在脚本初始化期间,会创建一个Controller实例。
  4. 在Controller初始化期间,会创建一个Script实例。
  5. 等等。

    您要实现的目标是相互引用类。 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;
        }
        ...
    }