繁体   English   中英

基于代理的模型中的Java NullPointerException

[英]Java NullPointerException in agent based model

我正在使用MASON库来运行基于代理的简单模型。

根据规范,我的意思是双击“描述”中的代理检查员。

但是,当我这样做时,出现以下控制台错误:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at sim.display.Display2D.createInspectors(Display2D.java:1737)
    at sim.display.Display2D$8.mouseClicked(Display2D.java:1392)

我去了Display2D.java:1737查找:

 public void createInspectors( final Rectangle2D.Double rect, final GUIState simulation )
        {
        Bag inspectors = new Bag();
        Bag names = new Bag();

        Bag[] hitObjects = objectsHitBy(rect);
        for(int x=0;x<hitObjects.length;x++)
            {
            FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
            for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
                {
                LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
                inspectors.add(p.portrayal.getInspector(wrapper,simulation));
                names.add(p.portrayal.getName(wrapper));
                }
            }
        simulation.controller.setInspectors(inspectors,names); //1737
        }

但是,这是一个库文件,因此我不熟悉它。

有什么建议吗?

图书馆:cs.gmu.edu/~eclab/projects/mason/

更新:

好吧,这很有趣...

我对检查器和名称的toString方法进行了回显,返回:

insepectors sim.util.Bag@1b2202a names sim.util.Bag@16b334d

好的,所以它们是袋子,是一种收藏。 时间来获取他们的大小...

insepectors 1 names 1

好,他们不是空的。

让我们关注错误堆栈

下一位:

at sim.display.Display2D$8.mouseClicked(Display2D.java:1392)

// add mouse listener for the inspectors
        insideDisplay.addMouseListener(new MouseAdapter()
            {
            public void mouseClicked(MouseEvent e) 
                {
                if (handleMouseEvent(e)) { repaint(); return; }
                else
                    {
                    // we only care about mouse button 1.  Perhaps in the future we may eliminate some key modifiers as well
                    int modifiers = e.getModifiers();
                    if ((modifiers & e.BUTTON1_MASK) == e.BUTTON1_MASK)
                        {
                        final Point point = e.getPoint();
                        if( e.getClickCount() == 2 )
                           1392-> createInspectors( new Rectangle2D.Double( point.x, point.y, 1, 1 ),
                                Display2D.this.simulation );
                        if (e.getClickCount() == 1 || e.getClickCount() == 2)  // in both situations
                            performSelection( new Rectangle2D.Double( point.x, point.y, 1, 1 ));
                        repaint();
                        }
                    }
                }

好的,该错误显然在CreateInspectors方法中:

public void createInspectors( final Rectangle2D.Double rect, final GUIState simulation )
        {
        Bag inspectors = new Bag();
        Bag names = new Bag();

        Bag[] hitObjects = objectsHitBy(rect);
        for(int x=0;x<hitObjects.length;x++)
            {
            FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
            for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
                {
                LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
                inspectors.add(p.portrayal.getInspector(wrapper,simulation));
                names.add(p.portrayal.getName(wrapper));
                }
            }
        System.out.println("insepectors " + inspectors.size() + " names " + names.size());
        simulation.controller.setInspectors(inspectors,names);
        }

我要做的第一件事:

System.out.println(rect.getCenterX() + " " + rect.getCenterY());

这给了我646.5 659.5。 看起来像座标是有意义的。

所以接下来我想看看hitObjects:

 System.out.println(hitObjects.length);

返回2。所以我在该坐标处有两个代理。

我认为NPE在这里:

for(int x=0;x<hitObjects.length;x++)
            {
            FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
            for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
                {
                LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
                inspectors.add(p.portrayal.getInspector(wrapper,simulation));
                names.add(p.portrayal.getName(wrapper));
                }
            }

外循环看起来不错,但内循环有问题。 建议吗?

实际上,我将写出自从您有能力以来就如何通过给定的库代码进行推理的方法。

您找到了代码。 这是一个好的开始。 您还发现了它所在的行:

 simulation.controller.setInspectors(inspectors,names); //1737

鉴于您对NPE的了解,您可以推断simulationcontrollernull

你知道吗 您可以针对可能设置失败或传递错误的代码进行推理吗? 您可以在代码中放置调试器断点或简单的println语句以确定哪个吗?

如果不是,而您正在使用IDE(可能是),则从刚打开的源代码中,在第1737行之前放置一个断点。当到达该行时,使用调试器检查变量simulation然后使用simulation.controller进行检查。看看哪个为null 确切的操作方法取决于您的IDE,但是使用XKCD的技术支持速查表不难发现。

然后,您可能会知道原因。 如果不是,请继续阅读源代码,例如,查找直至1737行的级别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM