【问题标题】:Lifetime of static (class) variables静态(类)变量的生命周期
【发布时间】:2011-05-28 19:08:34
【问题描述】:

在相当长的一段时间里,我很高兴地认为只要应用程序运行,静态 [实例] 变量就存在。然而,令我沮丧和震惊的是,我觉得这不是真的。

仅用于测试,我创建了一个静态字符串列表,并在我的主要 activity 类中覆盖了 onDestroy 方法以打印一条消息以验证应用程序是否退出。在onCreate 方法中,我只是添加了一个新的string,并打印了列表的内容。我发现列表的大小不断增加,并且之前添加的所有字符串值仍然存在。

我已经在某些地方 [甚至在 SO 上] 读到,只要应用程序存在,实例变量就存在,但我担心事实并非如此。

更准确地说,我是在使用 Facebook SDK for Android 时意识到这个问题的。我已经看到SessionEvents 类中的侦听器列表中的AuthListener 实例随着时间的推移不断增加。因此,无论何时启动应用程序并且用户使用 FB 登录,监听器方法都会被触发,其次数与 SessionEvents 类中存在的实例一样多。

以前有人观察过这一点,我在理解 android 的工作原理方面是否犯了一些重大错误?

什么给了?

感谢阅读!

[更新]
我接受BalusCrdineiu 的纠正。我真的不是要在这里制造关于实例和类变量的混淆。唉,在我匆忙发布我的问题时,我犯了一个我不想犯的错误。我非常清楚staticinstance 变量之间的区别。我只是打算写class 变量,并不能完全弄清楚是什么将静态变量称为instance 变量。

但是,我的问题仍然存在。 @MisterSquonk - 不,我不会在这里混淆我的Activity 何时结束以及应用程序何时被破坏。这是我在样本上尝试过的——我只有一个Activity,它充当Main。当我从这个Activity 按下返回按钮时,我假设Activity 从堆栈中删除并且应用程序也被破坏。我已启动任务管理器以验证我的应用不再运行。

【问题讨论】:

  • 静态变量 != 实例变量
  • 与您的问题没有直接关系,但参考您所说的内容......“在我的主要活动类中覆盖了 onDestroy 方法以打印一条消息以验证应用程序已退出” - 不要混淆与应用程序的活动。杀死一个活动并不一定会杀死应用程序(“应用程序”)。
  • @MisterSquonk - 不,我没有造成任何混淆。在我的特定应用程序中,我很确定 activity 的杀戮也意味着该应用程序不再运行。我使用任务管理器对其进行了验证,并更新了帖子以提及相同的内容。

标签: java android static


【解决方案1】:

您似乎没有区分静态变量和实例变量。静态变量是在类本身上定义的。实例变量只存在于类实例中。

例子:

class Test {
    public static int a;
}

变量a 是在类本身上定义的,而不是在类的实例上。每个实例都将访问 same 变量。如果一个实例将a 的值设置为5,则其他所有实例都将看到该值为5。一旦实例消失,该变量就不会消失,因为它与任何实例无关(它是一个类变量)。它会一直存在直到时间结束(或直到应用程序退出,以先到者为准)。

另一方面,下面的例子使用了一个实例变量:

class Test {
    public int a;
}

这个变量只能从类的实例中访问。每个实例都会有一个不同的变量副本。一旦实例被销毁,变量就会随之消失。


举例说明:

import java.util.List;
import java.util.ArrayList;

class Test {
  // instanceVar will be initialized whenever a new Test object is created
  private List<Integer> instanceVar = new ArrayList<Integer>();

  // staticVar will be initialized right now
  private static List<Integer> staticVar = new ArrayList<Integer>();

  public void updateInstanceVar() {
    instanceVar.add(1);
    instanceVar.add(2);
  }

  public void updateStaticVar() {
    staticVar.add(1);
    staticVar.add(2);
  }

  public static void main(String[] args) {
    Test test1 = new Test();
    test1.updateInstanceVar(); // test1.instanceVar = [1, 2]
    test1.updateStaticVar();   // Test.staticVar    = [1, 2]

    Test test2 = new Test();
    test2.updateInstanceVar(); // test2.instanceVar = [1, 2]
    test2.updateStaticVar();   // Test.staticVar    = [1, 2, 1, 2]
  }
}

【讨论】:

  • 感谢您指出这一点,是的 - 您完全正确。但是,正如我的帖子更新所暗示的那样,我希望我的问题的意图不会因为我犯的愚蠢错误而迷失。
【解决方案2】:

所以 - 我在 Android 开发者 Google 小组上发布了同样的问题 [很遗憾,我犯了同样的错误,将 static 变量称为 instance 变量]。

我收到了一些非常好的回复,尤其是来自 Kostya。我在该小组的互动帮助我掌握了 Android 平台的基本“规则”。

希望message thread 也对您有所帮助。

【讨论】:

    【解决方案3】:

    应用程序执行时实例变量会被销毁,但某些 gui 小部件默认情况下会保存其状态,然后在 onCreate 方法中将其恢复。

    【讨论】:

      猜你喜欢
      • 2011-09-12
      • 2013-07-27
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 2011-07-15
      • 1970-01-01
      • 1970-01-01
      • 2019-09-03
      相关资源
      最近更新 更多