0

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

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

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

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

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

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

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

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

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

提前致谢!

4

5 回答 5

1

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

请注意,某些语言,如 Haskell,只有不可变对象。

于 2013-04-06T21:37:22.793 回答
1

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

于 2013-04-06T21:38:22.397 回答
0

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

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

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

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

于 2013-04-06T21:43:53.570 回答
0

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

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

于 2013-04-06T21:39:23.707 回答
0

如果您不需要具有旧属性值的旧对象,请更改它。约定是改变它。否则审稿人会追查你为什么这样做。想知道现在在哪里使用旧对象。使代码更清晰更重要。

如果在许多地方、许多请求或循环中,内存和垃圾收集器暂停将是一个问题。简而言之,如果功能允许,请更改原始文件

于 2013-04-06T21:42:17.373 回答