Java 为什么我的singleton类抛出StackOverflower错误?

Java 为什么我的singleton类抛出StackOverflower错误?,java,singleton,stack-overflow,Java,Singleton,Stack Overflow,我一直在写一个程序。程序中的所有内容都由“Engine”类控制。因此,我把它变成了一个单身汉。这是我当前运行良好的代码 package org.bautista.cybersafe.core; import javax.swing.SwingUtilities; import org.bautista.cybersafe.ui.MainUI; import org.bautista.cybersafe.util.Cache; import org.bautista.cybersafe

我一直在写一个程序。程序中的所有内容都由“Engine”类控制。因此,我把它变成了一个单身汉。这是我当前运行良好的代码

    package org.bautista.cybersafe.core;

import javax.swing.SwingUtilities;

import org.bautista.cybersafe.ui.MainUI;
import org.bautista.cybersafe.util.Cache;
import org.bautista.cybersafe.util.Config;
import org.bautista.cybersafe.util.account.Account;
import org.bautista.cybersafe.util.account.AccountManager;
import org.bautista.cybersafe.util.user.User;
import org.bautista.cybersafe.util.user.UserManager;

public class Engine {
    private static Engine instance;
    private AccountManager accountManager;
    private final MainUI ui;
    private final UserManager userManager;
    private final Config config;
    private User currentUser;

    private Engine() {
        instance = this; //THIS IS LINE 22
        if (!Cache.cacheExists()) {
            if (!Cache.createCache()) {
                System.out.println("Error creating cache.");
            }
        }
        config = new Config();
        userManager = new UserManager();
        ui = new MainUI();
    }

    public static Engine getInstance() {
        return instance == null ? instance = new Engine() : instance;
    }

    public void setCurrentUser(User user) {
        currentUser = user;
    }

    public User getCurrentUser() {
        return currentUser;
    }

    public AccountManager getAccountManager() {
        return accountManager;
    }

    public Config getConfig() {
        return config;
    }

    public UserManager getUserManager() {
        return userManager;
    }

    public void logOut() {
        currentUser = null;
        accountManager = null;
        ui.showLogin();
    }

    public void openAccountViewer(final Account account) {
        ui.showAccount(account);
        ui.setTitle("Cyber Safe - [" + currentUser.getUsername() + "] -"
                + account.getName());
    }

    public void openCreateAccountScreen() {
        ui.showCreateAccount();
    }

    public void openCreateUserScreen() {
        ui.showCreateUser();
    }

    public void openLoginScreen() {
        ui.showLogin();
        ui.setTitle("Cyber Safe");
    }

    public void openSafeScreen() {
        if (accountManager == null) {
            accountManager = new AccountManager(currentUser);
        }
        ui.showSafe();
        ui.setTitle("Cyber Safe - [" + currentUser.getUsername() + "]");
    }

    public void refreshUI() {
        ui.refresh();
    }

    public void updateAccountPreviews() {
        ui.updateAccountScroller();
    }

    public void run() {
        try {
            SwingUtilities.invokeAndWait(() -> ui.setVisible(true));
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }

}
当我注释掉第22行时

instance = this;
我收到一个StackOverflower错误。当我调试程序时,我发现引擎构造函数被反复调用,就像它在执行递归一样,直到我最终得到错误。为什么会这样?我的getInstance方法不应该将实例作为“Engine”类的新实例启动吗

以下是stacktrace:

Exception in thread "main" java.lang.StackOverflowError
at java.io.InputStream.<init>(InputStream.java:45)
at java.io.FileInputStream.<init>(FileInputStream.java:123)
at org.bautista.cybersafe.util.Config.loadProperties(Config.java:67)
at org.bautista.cybersafe.util.Config.<init>(Config.java:29)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:28)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)

提前谢谢

堆栈跟踪显示以下循环:

at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
Engine.getInstance调用新引擎。 新引擎调用新用户管理器。 新的UserManager调用UserManager.loadUsers。 UserManager.loadUsers调用Engine.getInstance,但Engine.instance尚未分配,因为上一个新引擎调用尚未返回

这就是为什么在构造函数调用new UserManager之前,在构造函数中分配Engine.instance可以解决问题

您应该重新组织代码以防止初始化循环。初始化期间,UserManager和引擎不应相互依赖


请注意,按照另一个答案中的建议执行private static Engine instance=new Engine不会修复初始化循环。

堆栈跟踪显示以下循环:

at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
Engine.getInstance调用新引擎。 新引擎调用新用户管理器。 新的UserManager调用UserManager.loadUsers。 UserManager.loadUsers调用Engine.getInstance,但Engine.instance尚未分配,因为上一个新引擎调用尚未返回

这就是为什么在构造函数调用new UserManager之前,在构造函数中分配Engine.instance可以解决问题

您应该重新组织代码以防止初始化循环。初始化期间,UserManager和引擎不应相互依赖


请注意,按照另一个答案中的建议执行private static Engine instance=new Engine不会修复初始化循环。

是否在构成引擎类的任何其他类中创建新引擎?这是不可能的,构造函数是私有的。几乎每个类都调用Engine.getInstance方法@HoverCraftfullOfelsShow your stacktrace please.奇怪的是,错误表明它来自另一个类,但没有注释第22行是唯一可以修复它的东西@hovercraftfullofeels添加了所需的一切@hovercraftfullofeels是否在构成引擎类的任何其他类中创建了新引擎?这是不可能的,构造函数是私有的。几乎每个类都调用Engine.getInstance方法@HoverCraftfullOfelsShow your stacktrace please.奇怪的是,错误表明它来自另一个类,但没有注释第22行是唯一可以修复它的东西@HoverCraftfullofeels添加了所需的一切@HoverCraftfullofeels就是这样。好样的!非常感谢你!我会继续写下去:就是这样。好样的!非常感谢你!我将继续重新编写: