优雅与效率| java的

时间:2013-04-06 21:23:33

标签: java garbage-collection performance

我是Java的新手,我想知道什么是更好传统编程。

当我想要更改现有对象的属性时:

一种方法是简单地通过set函数设置值,看起来更有效:

anExistVar.setX(newValue);
anExistVar.setY(2);
anExistVar.setSomething(null);

另一种方法是创建一个新对象(在重写中),看起来更优雅和清晰(将一些工作留给垃圾收集器......):

anExistVar = new SomeClass(newValue, 2, null);

也许答案取决于我需要更改的值的数量? 也许在这种情况下,没有明显的效率差异?

(我的问题是指 JAVA 或系统管理动态内存的任何语言)

我读了一些关于这个主题的讨论,但我没有得到明确的答案。

提前致谢!

5 个答案:

答案 0 :(得分:1)

第二种方法允许您使用具有一些优点的不可变对象。例如,由于无法更改不可变对象,因此您无需复制它们:在某些情况下,这可能更有效。这使您每次需要更改值时都可以创建一个新对象,但gc会有效地收集生命周期较短的对象。

请注意,某些语言(如Haskell)只有不可变的ojbects。

答案 1 :(得分:1)

一般来说,做六个月后最有意义的事情。 Java针对新创建的对象进行了垃圾收集优化,因此效率也不会太大。

答案 2 :(得分:0)

这不取决于你想要的吗?第一个片段修改现有对象,而第二个片段创建一个新对象。对同一对象的引用将在版本1中看到新值,但在版本2中不会看到。

当它只是一个参考时:第一个更冗长,因此可能更容易理解。而且,构造函数应该只采取必要的东西。 (没有它,对象将毫无用处) 太多重载的构造函数也容易混淆。我认为最好明确说明每项任务。

答案 3 :(得分:0)

如果您不需要具有旧属性值的旧oblect,则更改它。惯例是改变它。否则审稿人会去寻找你为什么这样做。 想知道现在使用旧物体的地方。使更清晰的代码更重要。

如果因此在许多地方,许多请求或循环中,内存和垃圾收集器暂停将是一个问题。如果功能允许,请简短地更改orignal

答案 4 :(得分:0)

我认为答案取决于你究竟在这里尝试做什么。从概念上讲,根本问题是,程序员在更新其成员或将其完全重新分配为基本实体之后,是否会想到anExistVar你的程序?或者它只是旧东西的修改版本?

如果它只是一个修改过的版本,为什么要一次更新成员变量的所有?旧对象和新对象共享相同的名称和内存位置,但从逻辑上讲它们之间似乎没有任何关系。但请注意,如果您打算更新所有成员变量但未能这样做,您可能认为旧状态和新状态之间没有关系,因此没有意识到旧国家有一些保留。特别是,可能存在没有相应的公共set方法的私有成员变量,因此即使这是您的意图,您也可能无法完全转换对象。简而言之,这种对象的激进转变令人困惑,因为它不能立即清楚你在做什么或为什么,或者你是否真的会成功。但是,如果您认为修改后的对象仍然是基本相同的对象(例如,某些原始数据),则修改现有对象比制作部分忠实副本更有意义。 / p>

如果您正在创建一些全新的东西,那么最好将其声明为new对象。如果您希望旧对象和新对象之间存在某种关系,可以使用各种技术,例如static类成员来跟踪该实例的总数。已经实例化的类。或者,如果您希望新实例的构造部分由旧实例的公共属性确定,则将这些属性显式传递给构造函数。

就效率和垃圾收集器而言,可能没有理由担心任何一种方式。垃圾收集器的目的是减轻程序员明确删除事物的负担;你不能明确地控制它的行为,它的行为足够有效,你真的不必担心它。耗尽内存比使垃圾收集器负担过重更令人担忧。在您描述的特定情况下,是的,垃圾收集器将需要删除旧对象,但这不会对收集器的效率产生重大影响。维护对不再需要的对象的引用会有问题,因为垃圾收集器在以后引用它们时将无法收集这些对象;因为那不是你在这里所做的,所以最好从编程和逻辑的角度做任何最清晰的