静态块的执行

时间:2019-07-16 17:17:11

标签: java static

为什么此代码是编译错误?

class Test1{
    static {
        System.out.println(x);
    }
    static int x=10;
    }
}

以下代码可以编译并正常运行吗?

class Test2{    
    static int x=10;
    static {
        m1();
        System.out.println("base SB");
    }
    public static void main(String args[]){
        m1();
        System.out.println("base main method");
    }
    public static void m1(){
        System.out.println( y );
    }   
    static int y=20;
}

如果在这里声明y,为什么不在前面的代码中声明。 以下代码的输出是:

0 
base SB 
20
base main method 

我认为Java不支持正向引用。

2 个答案:

答案 0 :(得分:3)

答案可能不尽人意,但这只是语言的定义方式,特别是here

  

上述限制旨在在编译时捕获循环或其他形式的初始化

但是您可以像问题中那样轻松地解决限制,或者仅使用Test21.x而不是x来解决限制,因此它并不是特别可靠:

class Test21{
    static {
        // This is legal, but it is uninitialized, and thus prints 0.
        System.out.println(Test21.x);
    }
    static int x=10;
}

总的来说,最好强迫您跳过一圈,让您停下来思考自己在做什么,只有在您真的打算这样做时才继续进行

最终,这种语言无法完全阻止您用脚射击。这样做只会更加困难。

答案 1 :(得分:2)

您的第二个测试用例最初打印为零,我认为这对大多数人来说不是惯用语言。

这只是编译器不够聪明而无法捕获您可能犯的错误的情况。

在第一种情况下,它能够检测到前向参考-很幸运!否则,您的程序将在运行时打印为零,因为该变量尚未初始化。因此,编译器使您避免了可能的错误。

在第二种情况下,它无法检测到它,因为您已经引入了间接访问级别,并附加了对m1的方法调用-真不走运!

在理想情况下,第二个代码示例也不会编译。