修改循环内的对象有什么问题吗?

时间:2013-08-23 22:01:16

标签: java

public Collection<QueueMetrics> getAllGatewayQueueMetricsCurrent(String keywords)
{
    QueueMetrics qmInput = null;
    QueueMetrics qmImport = null ;
    QueueMetrics qmReport = null ;
    ArrayList<QueueMetrics> metrics = new ArrayList<QueueMetrics>();

    for (String keyword : keywords.split(",")){
        ConsoleServiceMBean console = getConsoleService(keyword);
        populateMessageCountStr(qmInput, keyword, console, "input");
        populateMessageCountStr(qmImport, keyword, console, "import");
        populateMessageCountStr(qmReport, keyword, console, "report");
    }
    metrics.add(qmInput);
    metrics.add(qmImport);
    metrics.add(qmReport);

    return metrics;
}

private void populateMessageCountStr(QueueMetrics qMetrics, String keyword, ConsoleServiceMBean console, String type)
{
    QueueMetrics tempMetric = console.getGatewayQueueMetricsCurrent(type, keyword);
            if( qMetrics == null ){
             qMetrics = tempMetric ;
    }else{
        qMetrics.setPendingMessageCountStr( qMetrics.getPendingMessageCountStr() + ", " + tempMetric.getPendingMessageCount());
         }

}

我尝试通过调用populateMessageCountStr并传入对象本身进行更新来更新上部for循环中的qmInput,qmImport和qmReport。在下一个循环中,将使用其他数据再次更新同一对象。但是,该程序的最终结果是qmInput,qmImport和qmReport都为null。谁知道为什么?为了提供更多信息,当我稍微更改一下上面的函数时:

        qmInput = populateMessageCountStr(qmInput, keyword, console, "input");
        qmImport = populateMessageCountStr(qmImport, keyword, console, "import");
        qmReport = populateMessageCountStr(qmReport, keyword, console, "report");

并且lower函数返回更新的QueueMetrics而不是void。程序按照已经过时的方式工作。有谁知道为什么原来的方式不起作用?我感谢任何有用的评论。

3 个答案:

答案 0 :(得分:2)

  

但是,该程序的最终结果是qmInput,qmImport和qmReport都为null。

因为,如果它等于QueueMetrics,那么您将在该方法中将传递的null引用重新分配给新对象,它将在第一次调用时进行。在这种情况下,原始引用仍将指向null。因此,对于该方法的所有进一步调用,它将保持null,因为条件qMetrics == null始终为 true

由于Java通过Value传递引用,因此将qMetrics重新分配给其他实例,将更改传递的引用副本的值。但它不会修改原始参考的参考值。

要解决此问题,只需从方法中返回修改后的引用(将populateMessageCounterStr()的返回类型更改为QueueMetrics,并将其分配给主叫方的原始引用。

答案 1 :(得分:0)

qMetrics在本地设置,对它的引用丢失。因此,除非您返回该引用,否则方法populateMessageCountStr的调用者将无法查看对它的引用。

if( qMetrics == null ){
             qMetrics = tempMetric ;

将其更改为

qmInput = populateMessageCountStr

并另外更改return qMetrics

中的返回类型和populateMessageCountStr

qMetrics为空的第一次迭代中,新实例被创建console.getGatewayQueue...(并假设它不返回null)qMetrics引用被返回并存储在qmInput中并且相同在后续迭代中传递给populateMessageCountStr

答案 2 :(得分:0)

在java中:

Object a = null;
Object b = a;
b = "foo";

留空,这是你的问题。 你想要做的是:

Object a = <something>;
Object b = a;
b.mutate();

这是安全的,因为b.mutate正在变异&lt;某事&gt;,所以有效的a.mutate()和b.mutate()是等价的。