我一直在写一个程序。程序中的所有内容都由“引擎”类控制。因此我把它变成了单身人士。这是我当前运行得很好的代码。
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错误。当我调试程序时,我发现重复调用Engine构造函数,好像它正在执行递归,直到我最终得到错误。为什么会这样?我的#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)
And here is the full project on Github
提前致谢!
答案 0 :(得分:4)
堆栈跟踪显示以下循环:
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()
来电new Engine()
new Engine()
来电new UserManager()
new UserManager()
来电UserManager.loadUsers()
UserManager.loadUsers()
已拨打Engine.getInstance()
,但尚未分配Engine.instance
,因为之前的new Engine()
来电尚未返回。
这就是在调用Engine.instance
之前在构造函数中分配new UserManager()
来解决问题的原因。
您应该重新组织代码以防止初始化循环。 <{1}}和UserManager
在初始化期间不应相互依赖。
请注意,按照另一个答案中的建议执行Engine
将无法修复初始化循环。