Java对象持久性

时间:2018-09-27 20:45:58

标签: java servlets

我正在尝试用更少的行来编写代码,而又不损失处理效率。考虑以下代码:

JSONArray arr = new JSONArray();
for(i = 0; i < 10; i++){
    JSONObject main = = new JSONObject();
    main.put("RedApples", i);
    main.put("GreenApples", i);
    arr.add(main);
}

现在我们知道这是错误的代码,因为JSONObject在循环内声明,因此您将声明10个不同的JSONObjects对象,这些对象将保留在内存中直到代码完成。我们应该要在数组外部声明JSONObject,而只需在循环内部进行设置即可。

现在函数呢?如果在函数内部有一个JSONObject声明,并且该函数被调用10次,它将全部10保留在内存中,或者函数结束时是否将内存完全转储?我在servlet中使用它。我已经尝试搜索此内容,但是与Servlet的其余部分相比,很难找到函数内部发生的情况。

3 个答案:

答案 0 :(得分:0)

您在这里混了几个字。在您的代码示例中,您没有创建对象,而是在声明原始类型为int的变量。此变量在堆栈上创建。每个变量都有一个作用域,在这种情况下,该作用域是循环的主体。该变量的值仅在其范围内有效,因此,每次迭代结束时,该变量将不再使用(可以回收其内存并用于其他原因)。

方法同样适用-它们声明一个范围,在该范围内声明的变量有效。函数返回时,已声明的变量将不再使用,并且可以回收其内存。

有关更多信息,请检查Local Variables and Scope

答案 1 :(得分:0)

  

所以您将声明10个不同的int对象,这些对象将保留在内存中,直到代码完成为止

不,这不是Java的工作方式。首先,原始类型的变量(例如int)不是对象。我不知道“直到代码完成”的确切含义,但是您在循环内声明的int变量不会保留在循环体之外的内存中。

在循环外声明该变量对效率或内存使用的影响很小。

请注意,您也可以像这样编写循环,而无需添加变量:

for(i = 0; i < 10; i++){
    setApples(i * 5);
}

但是实际上,这甚至与原始代码几乎完全相同。

担心像这样的微优化通常是不值得的。 JVM比大多数程序员意识到的要聪明得多-它包含许多复杂的优化,可以使您的代码快速运行。

答案 2 :(得分:0)

首先,您要在此处执行的操作称为“过早优化”。它在编写代码时会考虑效率问题,而不是编写可读,直接的代码。通常,这样会导致代码难以阅读和维护,并且在大多数情况下并不能真正提高程序效率。

[如果您想进行优化,请先使用良好的探查器进行分析,然后再在发现热点的地方开始更改代码。]

使用JSONObject解决新的代码示例:

因此,您需要一个JSONArray,其中包含10个事先不存在的不同JSONObject。无法避免创建这10个JSONObject,而这正是您的代码示例所做的。如果仅在循环外部创建一个JSONObject并将其字段设置为每个循环迭代的不同值,则最终将得到一个JSONArray,其中包含10倍的相同JSONObject,具有来自最新迭代的字段值,因为所有{{1} }调用只会修改您创建的单个对象,最后一组将获胜。如果要使用10个字段值不同的JSONObject,则需要10个实例,因为单个实例只能保存一组值,无论您将其添加到某个列表或数组的频率如何。