【问题标题】:Are java global variables guaranteed to initialize first?java全局变量是否保证首先初始化?
【发布时间】:2015-09-14 07:02:11
【问题描述】:

实际上不是全局变量,而只是类范围的变量。

例如,我有这样的初始化:

MyObj obj = new MyObj();

然后我就有了这个方法:

public void Foo(){
    obj.doSomething;
}

假设我无法使用构造函数(这与 android 相关)。是否保证在调用类中的任何方法之前始终初始化变量?

【问题讨论】:

  • “假设我不能使用构造函数(这是与 android 相关的)” - 嗯?!? Android允许你定义构造函数!
  • 哎呀,你是对的,即使是碎片..我会读更多关于它的,我弄错了

标签: java android static scope


【解决方案1】:

(要明确:1)Java 没有全局变量。 2) Java 有类(即static)字段和实例字段,以及局部变量。 3) 该示例似乎显示了一个实例字段,因此我假设 that 是您要询问的内容。)

java全局变量是否保证先初始化?

是的。除了我将在下面解释的病理情况。

创建对象时,按以下顺序完成以下事情:

  1. 对象以正确的对象类型在堆上分配,所有实例字段都“默认初始化”为零、false 或null

  2. super(...)this(...) 中的表达式被求值,并调用链上下一个类的构造函数。 (这会递归链式构造函数,以便首先执行 Object 构造函数。)

  3. 实例变量初始化器和任何实例初始化器块按顺序执行。

  4. 构造函数的主体被执行。

  5. 构造函数返回。

所有这一切都发生在你执行new SomeClass(...)时。

因此,在您的示例中(如所写),您可以确保实例变量 obj 将在调用您的方法之前被初始化。


现在是病理病例。考虑一下:

public class Foo {

    private int a = someMethod();
    private int b = 42;

    public Foo() {
    }
    
    private int someMethod() {
        return this.b;
    }
}

在这种情况下,a 的初始化程序将调用 someMethod before b 已初始化,因此 someMethod 将返回默认初始值 b .. 。 零。您还可以使用实例初始化块“实现”病态示例。但是,如果您在 Foo 构造函数中调用了 someMethod,则可以确定实例变量的初始化程序将已被执行。

确实还有其他病理情况需要考虑。如果上述someMethod 的实现是调用另一个类中的方法,将this 作为参数传递,那么另一个类可以调用部分初始化Foo 实例上的方法。 (这称为不安全的发布。如果部分初始化的实例可以被另一个线程访问,则尤其阴险,因为这会使各种 Java 内存模型保证无效。)

【讨论】:

  • 谢谢,很高兴知道。原来我的问题只是 android 生命周期的问题。所以如果在我的片段中声明并初始化一个像这样的实例变量,那么初始化发生在片段附加到一个活动之前,这意味着它实际上还不能做任何事情。
【解决方案2】:

是否保证变量总是在类中的任何方法被调用之前被初始化?

是的。你是对的。它已经初始化,因为它甚至在构造函数之上声明并准备好以后使用。

这取决于你,你将在哪里使用该实例成员,天气在构造函数中或稍后在方法中,但它保证在构造函数调用之前初始化。

【讨论】:

    【解决方案3】:

    首先,它不是一个全局变量。它是一个实例变量。保证在调用构造函数之前初始化,所以保证在调用Foo的时候初始化。

    【讨论】:

      【解决方案4】:

      这就是Myobj()。它是一个默认构造函数,如果您在类中显式定义构造函数,它将被覆盖。 只要你创建了它的对象(参考变量),所有变量都会得到它的内存,而一旦 new 关键字被编译,甚至在你的语句 MyObj obj = new MyObj(); 被编译之前,类就会得到它的空间。

      【讨论】:

      • 如果我这样做 Myobj obj = someMethod() 会怎样?是只有new关键字保证,还是总是保证先编译?
      • 其实。 MyObj 是无参数构造函数。如果该类根本没有(明确)定义任何构造函数,则它只是 >>default
      • 类只有在使用new 关键字后才会获得它的空间。在变量的情况下相同。所有变量只有在对象(引用变量)由一个类组成之后才能在内存中获得空间。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      相关资源
      最近更新 更多