0

假设有两个类,ObjectA 和 ObjectB。ObjectA 类有一个创建类对象的方法,ObjectB如下所示:

private ObjectB createObjectB() {
    Object b = new ObjectB();
    return b;
 }

我想跟踪ObjectB. 有什么更好的方法来做到这一点?

  • ArrayList以内部类的形式跟踪所有对象ObjectA
  • 或者里面的一些类变量ObjectB

每种方法的优缺点是什么?如果我知道ObjectB对象只会从 ObjectA 中的这一种方法创建,这会有所不同吗?

请注意,永远只有一个 的实例ObjectA,但 的实例的数量ObjectB是可变的。

4

6 回答 6

1

如果您想从代码的不相关部分访问所有创建的对象,您只需要“跟踪”以这种方式创建的对象。否则 1)创建的对象将由变量保存,因此您可以访问它; 2)当没有更多对该对象的引用(因此无法访问)时,垃圾收集器最终将清理内存。

如果您确实跟踪它们,请记住,当您在集合中有对象时,GC 无法释放内存,这可能导致内存不足错误

于 2012-06-07T20:49:34.230 回答
0

如果只有一个ObjectA实例,并且它有一个createB方法,我会将列表保留在ObjectA 实例本身上。但实际上我认为这并不重要。

public ObjectB createB(){
   Object B = new ObjectB();
   allBs.add(b); // assuming some sort of List
   return b;
}

我很想知道你为什么要这样做。您可能会遇到线程问题,具体取决于您的应用程序及其架构。

于 2012-06-07T20:48:17.967 回答
0

在 ObjectB 中保存一个列表是没有意义的,但是如果您需要对您创建的所有 B 对象的引用,那么在 ObjectA 中的列表将是有意义的。

于 2012-06-07T20:49:17.980 回答
0

根据您对 ObjectC 的看法,我认为 ObjectA(和 C)维护 ObjectB 的数组是最有意义的。(实际上,如果您希望添加和减去 B,我建议使用某种集合而不是数组)。

然后,您可以创建一个方法来返回 A 创建的 B 的数量,例如 A.countB()

如果您发现自己需要创建 B 的总数并且您不能使用 A.countB()+C.countB(),那么您有两个选择:B 中的静态映射,其中键是创建者对象(A、C 或其他),其值是 B 的集合。

我不鼓励这样做有几个原因,主要是创建的对象会挂起(所以没有 GC,以及潜在的内存问题)。

另一种方法是使用管理器类来创建和跟踪 B 并在完成实例后非常小心地取消引用。

于 2012-06-07T21:58:18.150 回答
0

这取决于您需要实现的目标。(顺便说一句,这是一个坏名字)的实例ObjectB应该能够相互交谈吗?如果是这样,那么您需要在类中创建一个全局变量(即一个static字段),或者您必须保留列表ObjectA并将其“注入”到每个实例中ObjectB- 这意味着您需要在两个地方都保留一个引用.

如果 的实例ObjectB不需要相互交谈,通常将列表保留在ObjectA.

但大多数情况下,根本没有必要保留一份清单。这甚至可能很危险,因为您必须确保列表在耗尽所有内存之前不会增长。

一般规则是:避免不必要的依赖。通过保留一个列表,您引入了一个有成本的依赖项(例如,在维护中,您需要首先编写代码)。

永远警惕你编写的东西的成本——很容易让这些廉价的东西积累成真正昂贵的依赖关系,扼杀你。

于 2012-06-07T20:58:06.117 回答
0

对我来说,对象 A 和对象 C 是管理对象 B 实例的类。

我有一个类似的场景,我需要跟踪作为基本服务类的子类的不同服务(在我的例子中,对象 B 是基类)。

要创建/启动/停止/重新启动/删除这些服务,我有 2 个管理器类,用于两种不同的目的(如您的情况下的对象 A 和对象 C)。

在两个管理器类中,我都有一个 HashMap

您可以有一个方法来停止/启动/创建/销毁/删除类 A 或 C 中的 B 对象,该方法采用“名称”ob 对象 B 并在对象 B 上启动相应的操作。

作为最佳实践,在您的 SessionContextListener 中始终确保调用停止/删除操作以删除此 HashMap 中添加的对象。

于 2012-06-07T21:43:38.283 回答