2

我的问题相当具体,因此很难搜索。我正在编程 Java 并学习该语言。我设计了一个名为 Experiment 的类,我在其中定义了所有实验的通用函数和默认参数。

对于每个特定的实验,比如 ExperimentA,然后我将 Experiment 子类化。每次我想运行实验 A 时,我都会创建一个 ExperimentA 的实例,将参数传递给构造函数,然后该构造函数会覆盖 Experiment 中定义的默认参数。我有两个问题。我在同一篇文章中发布了这两个问题,因为我认为它们可能相关。

1)以上设计合理吗?最初我想使用接口,但我发现接口中的值必须是常量,因此无法覆盖参数。

2) 在更改参数运行多个相同类型的后续实验时,我遇到了内存泄漏问题。

for(int na:ArrayOfIntegers) {
    Experiment e1 = new ExperimentA(na,otherArgs);
    Experiment.runExperiment(e1);
}

由于某些原因,即使在 e1 已分配给新的 ExperimentA 对象之后,由 e1 对象保留的对象仍会在堆中保持活动状态。我知道这是一个非常普遍的问题,但我是 Java 新手,一些关于问题可能是什么的猜测可以帮助我。

我知道的唯一不当行为是将 Experiment 中的默认变量设为 public,而不是私有并使用 getter,但我看不出在这种情况下这会如何导致任何问题。在执行 runExperiment() 函数并创建另一个 ExperimentA 对象后,基本上没有对 e1 对象的引用。有任何想法吗?

4

2 回答 2

0

1) 你是否考虑过通过一个名为 Experiment 的类和一个单独的 IExperiment 接口来提供默认参数,该接口只有一个像“run”这样的方法?这样你就可以让你的默认参数更具可配置性。可能还有其他选择,您面临的问题的一些示例会有所帮助。

2) 当您从 getter 返回一个对象时,您正在为调用者提供对该对象的引用。所以在这个例子中,“bar”会一直存在,直到 getBar() 的调用者不再需要它:

public class Foo {
    private Bar bar;
    ...
    public Bar getBar() { return bar; }
}

您可以改为返回 bar 的克隆。您可能需要覆盖 Bar 类上 clone() 的默认实现,以确保它是深层副本(所有私有值都独立于原始 Bar)。

于 2013-08-06T14:14:29.660 回答
0

你的Experiment类是静态的,你传递e1给它的方法。

的内容是runExperiment什么?您是否有任何代码,例如,将参数存储在数组中?

如果对创建的对象有任何引用,则不能对其进行垃圾收集。虽然它Experiment是静态的,但我认为它的内部结构应该有一些管理例程来清理已经完成和一次性的实验。

于 2013-08-06T14:06:04.140 回答