5

我真的不知道如何正确解释这个错误......

当我将此方法添加到我的控制器类时,它就开始了:

public void loadPlayerComboBox() {
    try{
        final PreparedStatement collectPlayerNames = 
                ConnectionManager.getConnection().prepareStatement("SELECT "+PLAYER_NAME+"  FROM PLAYERS");
        final ResultSet playerNameResults = collectPlayerNames.executeQuery();
        while(playerNameResults.next()){
            IViewManager.Util.getInstance().getMyContainerPane().getMyPlayerManagerPane().getPlayerNameList()
            .add(playerNameResults.getString(PLAYER_NAME));
        }
    }catch(final SQLException e){
        System.out.println("SQLException. Reason: " + e.getMessage());
    }
}

而且我已经确认没有这个方法(由一个类调用,在程序启动时)我没有错误。

我的错误?当我从eclipse运行时,程序开始加载框架的顶部栏出现,但实际内容没有。

在此处输入图像描述

除此之外,还有一个奇怪的空盒子,我相信这是由多个进程启动引起的。

我相信这是由堆栈溢出引起的,因为我的 getInstance() 方法递归地相互调用。由于某种原因,我无法取回堆栈跟踪,目前调试屏幕只是空白。我检查了我的 .log 并且没有与该时间戳对应的错误。我不知道他们怎么能互相打电话。这是 ViewManager 方法:

static class Util {
    static private IViewManager viewManager = null;
    static public synchronized IViewManager getInstance() {
            if (viewManager == null) {
                    viewManager = new ViewManager();
            }
            return viewManager;
    }
}

和构造函数:

public ViewManager(){
    super("Tony Larp DB Manager");
    this.setVisible(true);
    this.setDefaultCloseOperation(3);
    myContainerPane = new ContainerPane();
    myContentMenu = new ContentMenu();
    IController.Util.getInstance();
    IPlayerCharacterManager.Util.getInstance();
    this.setJMenuBar(myContentMenu);
    this.getContentPane().add(myContainerPane);
    this.pack();        
}

IController.Util.getInstance() 方法是相同的,只是它调用的类和对象的名称不同。双重检查锁定只会导致我的启动器中的第一个 IViewManager.getInstance() 实例返回一个空指针,这是同步块的开头。

澄清一下,程序IViewManager.Util.getInstance()第一次在启动器中调用,然后IController.Util.getInstance()在上面的构造函数中第一次调用。之后,对它的所有调用都应该只返回实例。

什么会导致这种错误?我怎么能开始修复它?

4

2 回答 2

1

希望这听起来不难:您的代码结构非常糟糕:-/

我无法为你的问题提供解决方案。如果我能看到你的完整代码,也许我可以。但我想给你更一般的帮助。也许那时您可以自己解决问题。

您应该尝试简化和清理您的结构。这里有一些建议:

如果您的 UI 中需要一些单例,我认为这没问题。一般来说,单身人士可能是一种“难闻的气味”,但你总是要小心。在您的情况下,您可以去除延迟初始化、同步等。

简单地写

static class Util {
    public static final IViewManager viewManager = new ViewManager();
}

如果你真的只想要一个 ViewManager 在你的 UI 中(听起来很合理)。

那你就不用再打电话... .Util.getInstance()了。简单地写Util.viewManager

您应该尝试实现关注点分离。让一个班级只做一件事。ViewManager 管理视图。没有其他的。视图类可能负责对话框的布局。但是视图类不应该知道如何查询数据库来填充组合框。您的视图类甚至必须知道 SQL。而且您的视图类也知道MyPlayerManagerPane的怪异方式, 这是其他类的所有任务。

当您需要游戏或玩家数据时,也许您想询问类似 GameRepository 的东西?你可以引入这样的课程。然后你可以给你的视图一个 GameRepository 类的实例,在你的视图中你可以说:

...
ComboBoxModel playersModel = createPlayersModel(gameRepository.getPlayers());
playersCombobox.setModel(playersModel);
...

通过这种方式,您可以获得相对较小的课程。这样的类很容易自己测试。如果您在开发过程中的某个时刻出现奇怪的行为,您可以很快找到原因。

希望你明白了;-)

于 2012-07-31T15:10:30.010 回答
0

这种行为表明你有某种无限循环。有些地方你已经跨越了你的线程(一个线程中的一个方法调用另一个方法中的一个方法,它调用第一个)。

两者都没有完成构建,因此您的单身人士没有要调用的实例。相反,他们不断尝试无限地实例化彼此。回过头来重新考虑一下你的单例代码线程是多么独立。

于 2012-09-03T12:16:40.110 回答