代码之家  ›  专栏  ›  技术社区  ›  nantitv

java类加载器的准备阶段和初始化阶段

  •  0
  • nantitv  · 技术社区  · 11 年前

    我无法理解以下几行之间的区别( http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.2 )

    A) 准备工作包括将静态字段初始化为默认值。

    B) 类的初始化包括为类中声明的静态字段(类变量)执行初始化器。

    这是否意味着“a”将在“准备”阶段分配默认值,而“b”将在初始化阶段分配值:

    static int a;  
    static int b=2;
    
    2 回复  |  直到 8 年前
        1
  •  2
  •   RealSkeptic    11 年前

    “初始化为默认值”表示字段设置为以下值:

    • 布尔值:false
    • int,长,字节,短:0
    • 双精度,浮点:+0.0
    • 字符:'\u0000'
    • 引用类型:null

    “通过执行初始化器初始化”意味着现在将对分配给这些静态字段的表达式求值并分配给它们。

    所以,在“准备”阶段 a b 将创建并接收值 0 在“初始化”阶段, b 将接收值 2 .


    使用具有副作用的方法很容易验证这一点。而不是将简单的“2”分配给 b ,我们正在调用一个返回值的静态方法 2. ,但在执行此操作之前,它还会打印有关变量的信息:

    public class SimpleTest {
    
        private static int a;
        private static int b = printAAndBReturning2("initializer");
    
        static {
            printAAndBReturning2("static initializing block");
        }
    
        public static void main(String[] args) {
    
            printAAndBReturning2("main");
    
        }
    
        public static int printAAndBReturning2(String where) {
            System.out.printf("In %s a is %d and b is %d%n", where, SimpleTest.a, SimpleTest.b);
            return 2;
        }
    }
    

    输出为:

    In initializer a is 0 and b is 0
    In static initializing block a is 0 and b is 2
    In main a is 0 and b is 2

    本演示还用于警告您使用在初始化阶段运行的方法。

        2
  •  0
  •   sashaaero    11 年前

    基本类型的所有字段将自动初始化为默认值。
    对于int为0。所以 a == 0 。您可以检查默认值 here .
    它在非基元类型(类)上有区别。
    所以
    Font a; -> a == null (如果您尝试使用 a 你会得到 a is not initialized .
    Font b = new Font("Dialog", 16, Font.BOLD); -> b == ... (我想你明白了)。