以静态方式创建对象

时间:2012-05-16 07:25:58

标签: java static

有人能解释一下Java如何执行这段代码吗?我的意思是执行每个语句的顺序。

public class Foo
{
    boolean flag = sFlag;
    static Foo foo = new Foo();
    static boolean sFlag = true;

    public static void main(String[] args)
    {
        System.out.println(foo.flag);
    }
}

输出:

false

5 个答案:

答案 0 :(得分:104)

  • 类初始化开始。最初,foo为空,sFlag为假
  • 第一个静态变量初始值设定项(foo)运行:
    • 创建了Foo的新实例
    • flag的实例变量初始化程序执行 - 当前sFlag为false,因此flag的值为false
  • 执行第二个静态变量初始值设定项(sFlag),将值设置为true
  • 类初始化完成
  • main运行,打印出foo.flag,这是假的

请注意,如果sFlag被声明为final,则会将其视为编译时常量,此时对它的所有引用基本上都会被内联到true,所以foo.flag也是如此。

答案 1 :(得分:12)

foo在类的静态初始化期间实例化,并且在初始化sFlag之前,并且布尔值的默认值为false。

  1. 已加载课程
  2. Foo初始化为实例

    2.a实例成员标志初始化为sFlag的值(默认为false

  3. sFlag初始化为 true
  4. 有关详细信息,请参阅JLS §12.4

答案 2 :(得分:5)

加载课程时,sFlagfoo字段已初始化,但foo首先被初始化!
字段flagsFlag是布尔值,不能为空,因此默认情况下,sFlag在初始化时仍为false,foo仍然为false。 flag = sFlag之后的flag是假的。就是这样

答案 3 :(得分:2)

初始化操作的一般顺序是(在加载类之后和首次使用之前):

  1. 静态(类)代码块按顺序显示在代码
  2. 对象代码块按顺序出现在代码中(初始化块和赋值)。
  3. 构造
  4. 当然,我不会将构造函数和函数体引用为上面的代码块

    我不知道final static字段怎么样。看起来它们遵循static字段的规则,并且在声明之前它们不能被引用,尽管先前的注释它们是在编译步骤初始化的。如果在编译错误之前引用它们:

    Example.java:8: illegal forward reference
            System.err.println("1st static block j=" + j);
    

    也许final static字段可以初始化并编译到类文件中,但这不是一般规则,在声明之前仍然无法引用它们。

    检查初始化顺序的示例代码:

    class Example {    
    
        final static int j = 5;
    
        {
            System.err.println("1st initializer j=" + j);
        }
    
        static {
            System.err.println("1st static block j=" + j);
        }
    
        static {
            System.err.println("2nd static block j=" + j);
        }
    
        final static java.math.BigInteger i = new java.math.BigInteger("1") {    
            {
                System.err.println("final static anonymous class initializer");
            }
        };
    
        Example() {
            System.err.println("Constructor");
        }
    
        static {
            System.err.println("3nd static block j=" + j);
        }
    
        {
            System.err.println("2nd initializer");
        }
    
        public static void main(String[] args) {
            System.err.println("The main beginning.");
            Example ex = new Example();
            System.err.println("The main end.");
        } 
    }
    

    上面的代码片段打印:

    1st static block j=5
    2nd static block j=5
    final static anonymous class initializer
    3nd static block j=5
    The main beginning.
    1st initializer j=5
    2nd initializer
    Constructor
    The main end.
    

答案 4 :(得分:1)

在第一个静态字段应该运行并在第一个内联!所以在第一行4然后5将运行,所以首先初始化foo,因为我们知道默认情况下布尔变量被初始化为假,所以首先,当foo初始化时,flag的字段是sflag,这是假的,然后sfalsg变为true不会改变旗帜(没有关系),然后在最后的主要运行和打印错误的falg! 我希望有用!成功