【问题标题】:where to initiate object in java在java中启动对象的位置
【发布时间】:2012-06-28 10:18:05
【问题描述】:

这个问题与我对另一个问题的回答有关。 原问题是here

谁能解释为什么错误代码会按照 cmets 中解释的方式失败(因为它是伪代码)

 // bad code
        ResultSet rs = getDataFromDBMS("Select * from [tableName];");

            //temp uses a collection member within it to hold a list of column names to data value pairs (hashmap<String,String>)
        Object temp = new objectToHoldInfoFromResultSet();

        // loop over the result set
        while (rs.next)// for each row in the result set
        {
            for (int i = 1; i <= rs.getNumberColums; i++) {
                temp.add(infoAboutColumn);
            }
            temp.printInfo();// always prints correct (ie current) info
                    //the print just takes the hashmap member and asks for a       
                    //toString() on it
            anotherObject(makeUseOf(temp));// always uses info from first
                   //iteration. Essentially grabs the hashMap member of temp, and puts
                   //this into another collection of type 
                   //HashMap< HashMap<String,String>, temp> see the linked question
                   //for more detail.

        }

        // Seemingly each loop into the while the temp.doSomethingToData(); uses
        // the temp object created in the first iteration

        // good code
        ResultSet rs = getDataFromDBMS("Select * from [tableName];");

        // loop over the result set
        while (rs.next)// for each row in the result set
        {
            Object temp = new objectToHoldInfoFromResultSet();// moving
                                                                // declaration
                                                                // of temp into
                                                                // the while
                                                                // loop solves
                                                                // the problem.
            for (int i = 1; i <= rs.getNumberColums; i++) {
                temp.add(infoAboutColumn);
            }
            temp.printInfo();// always prints correct (ie current) info

            anotherObject(makeUseOf(temp));// also uses the correct (ie current)
                                            // info.

        }

【问题讨论】:

  • 嗯,你在这里遇到什么问题?
  • 老兄。我们必须找到问题并解决答案吗??
  • 把整个问题放在这里,不要把其他问题的答案发给我们。
  • 您发布的代码有很多缺陷,最糟糕的可能是它不是有效的Java。您正在给那些想要帮助您完成任务的人增加负担,而这些任务是您作为提问者的责任。
  • 我很欣赏您的 cmets,但似乎下面的 Peter Torok 能够理解我的问题,并提供了一个我认为令人满意的答案。 @AkhilDev 哈哈,确实,我有一个答案,但它提出了一个新问题,所以为了简洁起见,我剪掉了我的答案。 Marko Topolnik:对不起,我可能应该说我提供的是“伪代码”,我从来没有说过它是 java,除了标签,因为我知道代码不是好的 java

标签: java while-loop


【解决方案1】:

如果不知道 temp.printInfo()makeUseOf() 在做什么,我们无法可靠地回答这个问题。不过,按照您描述的方式实现它们很容易。

当您在循环外实例化temp 时,您将在循环的所有迭代中使用相同的对象。因此,它可以从每次迭代中收集数据(例如,收集到一个集合中)。然后,方法可以获取当前迭代中累积的数据,以及任何先前迭代中累积的数据,如果不是故意的,这可能会导致问题。

所以让我们假设temp 包含一个集合,并且在每次迭代中,结果集中的一列被添加到其中。现在,如果实现temp.printInfo() 来打印关于此集合中last 元素的信息,而实现makeUseOf() 来处理集合中的first 元素,你得到你观察到的行为。

OTOH 当您在循环内实例化 temp 时,您将在每次迭代中获得一个新的、不同的对象,它不会“记住”来自早期迭代的任何数据。因此,即使使用上述temp.printInfo()makeUseOf() 的实现,您也会得到正确的结果。

【讨论】:

  • 当我用 anotherObjectMakeUseOf(temp) 传递我的临时对象时,我没有指定任何有关信息的内容,所以我认为它很可能只是拉动它找到的第一个对象。我会接受你的回答,因为它合理地解释了观察到的行为(即使这种行为没有具体实施)。感谢您抽出额外的时间来解决我的“低效率问题”(因此 +1)大卫
  • 进一步的调查让我意识到这正是正在发生的事情。我以编程方式从临时对象中获取一个成员,但我猜编译器将其识别为“相同对象”,因此将它的引用复制到与派生密钥信息相关的值槽中,这听起来可能吗?跨度>
  • @DaveM,我不认为(Java)编译器正在做这样的优化 - JIT 可能会做类似的事情,但只有在代码运行之后很多次。但是如果它是同一个父对象,并且在调用之间没有修改有问题的成员,那么每次都会得到相同的成员对象。
【解决方案2】:

我不知道为什么一个好一个坏。我的猜测(不知道 objectToHoldInfoFromResultSet 和其他方法的行为是什么)如下:

在第一种情况下,“objectToHoldInfoFromResultSet”(应该大写)每次都创建一次

temp.add(infoAboutColumn);

被调用,新的记录数据被添加到对象中。我猜应该为每条记录清除此信息……否则你会得到很多重复。通过重新初始化持有者对象来处理复制。 IE。 (1 2 3 4 5 6) 而不是 (1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6)。

不知道各种礼物,我也无话可说。

【讨论】:

  • 我有点期待临时对象的新数据会覆盖旧信息。但似乎并非如此,您和彼得斯的答案是完美的,所以感谢您抽出宝贵时间(+1 努力解决我的不足问题
猜你喜欢
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多