【问题标题】:Using static modifier to track object instances使用静态修改器跟踪对象实例
【发布时间】:2012-12-08 15:06:37
【问题描述】:

我目前正在编写一个 Android 应用程序,我有一个关于何时使用静态方法/字段的更高级别的问题。

我的应用跟踪不同活动的时间使用情况,每个活动都是一个类的实例。我需要一个可以返回这个类的所有实例的方法。

像这样在我的 Activity 类中放置一个静态方法/字段是不是糟糕的设计:

static ArrayList<Activity> allInstances;    
public static void addToComprehensiveList(Activity a) {
    if(allInstances == null)
        allInstances = new ArrayList<Activity>();
    allInstances.add(a);
}
public static ArrayList<Activity> getComprehensiveList() {
    return allInstances;
}

这里的正确设计选择是什么?

【问题讨论】:

  • 看看单例模式。这种设计可能不是最好的方法,但效果很好。

标签: java android static instance


【解决方案1】:

保持实例的静态列表是相当安全和正常的事情。主要问题与您将项目添加到列表时有关。

例如,如果Activity 有一个在启动时调用addToComprehensiveList(this) 的非平凡构造函数,则有时未完全初始化的对象位于可公开访问的列表中。如果您的程序是单线程的,这并不太危险 - 除非构造函数稍后抛出异常,在这种情况下,对象会以未完全初始化的状态留在列表中。

解决此问题的一种安全方法是在工厂方法中创建实例,该方法在创建对象后将其添加到列表中。当然,如果没有子类,只要添加到列表中作为构造函数中的最后一条语句就可以了。

这里的另一个危险是getComprehensiveList() 返回对其实例列表的引用,这意味着客户端代码可能会在您的类不知道的情况下修改该列表。即使客户端只是遍历列表,如果您在其迭代期间创建一个新 Activity,您也会得到一个商品化异常。更安全的方法是返回列表的副本。

【讨论】:

  • 我意识到这个答案有点长,但是,确实应该指出,这个答案只在静态值和方法的单线程使用中是正确的。在多线程用例中(这里很可能是这种情况 - 它 android),使用这个系统可能会导致许多意想不到的“功能”。
【解决方案2】:

根据我在压力大或记忆力消耗大的情况下做这样的事情的经验:

static ArrayList<Activity> allInstances; 

不保证可用。 VM 可以将其清空,这就是 Singleton 可能更安全的原因。

【讨论】:

  • 如果这是维基百科,我会在is not guaranteed to be available. 之后直接插入一个需要引用标记
  • “根据我的经验”,引用将是我的 SO 句柄
  • 我很难相信静态变量不可用并且虚拟机可以“将其“清空”。
  • 好吧,我使用这个概念来管理 libgdx 游戏中跨活动的实例,过了一会儿,静态为空。我从来没有在我的代码中取消它,所以为什么我建议单例。我不知道 dalvik 的内部结构,但静态并不安全/有保证。
  • 我发现的一个来源说“(...)静态变量,每个类加载器,而不是每个虚拟机”。 tech.puredanger.com/2007/07/03/pattern-hate-singleton 。这可能是您体验的原因吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2015-04-11
  • 2011-01-21
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多