zoukankan      html  css  js  c++  java
  • Initialization and Class loading

      可以说,类的代码在初次使用时才加载。这通常指加载发生于创建类的第一个对象之时,但当访问

    static域或static方法时,也会发生加载(通过下面的这段代码验证)。

    class LoadTest {
        // The static clause is executed upon class loading:
        static {
            System.out.println("Loading LoadTest");
        }
        static void staticMember() {}
        static int i = 0;
    }
    public class classLoading {
        public static void main(String args[]) {
            System.out.println("Calling static member");
            //new LoadTest();    // 1
            //LoadTest.staticMember();    // 2
            LoadTest.i++;    // 3
            System.out.println("Creating an object");
        }
    }

      Output:

    lxw@22:39:26:~/eclipse/java/javaComLine$ java classLoading 
    Calling static member
    Loading LoadTest
    Creating an object

      无论保留语句1,语句2还是语句3,代码运行结果都是上面的结果。

      所有的static对象和static代码段会在加载时按照程序中的顺序(定义类时的书写顺序)而依次初始化。

      本文将以下面的代码为例展开论述: 

    class Insect {
      private int i = 9;
      protected int j;
      Insect() {
        System.out.println("i = " + i + ", j = " + j);
        j = 39;
      }
      private static int x1 =
        printInit("static Insect.x1 initialized");
      static int printInit(String s) {
        System.out.println(s);
        return 47;
      }
    }
    
    public class Beetle extends Insect {
      private int k = printInit("Beetle.k initialized");
      public Beetle() {
        System.out.println("k = " + k);
        System.out.println("j = " + j);
      }
      private static int x2 =
        printInit("static Beetle.x2 initialized");
      public static void main(String[] args) {
        System.out.println("Beetle constructor");
        //Beetle b = new Beetle();    // 1 
        //Beetle b;    //2
      }
    }

    Output:

    lxw@11:03:16:~/eclipse/java/javaComLine$ java Beetle 
    static Insect.x1 initialized
    static Beetle.x2 initialized
    Beetle constructor

    Analyze:

      Part 1.

      上面的代码执行时,首先将试图访问main(),于是开始启动并找出Beetle类的编译代码,在加载的过程中

    编译器注意到它有一个基类,于是先对基类进行加载。此时基类中的static初始化开始被执行,然后执行导出

    类中的static初始化。”先执行基类然后再执行导出类“的原因是导出类的static初始化可能会依赖于基类成员是

    否被初始化。

      简略的说就是:基类的static数据成员初始化 -> 导出类的static数据成员初始化 -> main()

      至此,不管代码中是否创建一个基类或导出类的对象都执行这些步骤。 

      Part 2.

      更改上面的代码,将语句2的注释去掉,则运行结果与上面的结果相同。

      Part3.

      更改上面的代码,将语句1的注释去掉:

      Output:  

    lxw@22:55:00:~/eclipse/java/javaComLine$ java Beetle 
    static Insect.x1 initialized
    static Beetle.x2 initialized
    Beetle constructor
    i = 9, j = 0
    Beetle.k initialized
    k = 47
    j = 39

      请注意各个输出的顺序。当用new创建导出类的一个对象时,其执行顺序如下:

      1. 基类初始化:先是基类的非静态成员初始化,然后是基类构造器的执行

      2. 导出类初始化:先是导出类的非静态成员初始化,然后是导出类构造器的执行

  • 相关阅读:
    [转载]android开发手册
    [转载]windows phone7 学习笔记10——生命周期/墓碑化
    [转载]Windows Phone 系列 本地数据存储
    【转载】windows phone7 学习笔记12——推送通知服务
    【转载】windows phone7 学习笔记15——Bing Maps
    [转载]WP7交互特性浅析及APP设计探究
    【】windows phone7 学习笔记11——启动器与选择器
    [转载]支持的 Windows Phone 媒体编解码器
    【转载】wp7屏幕截图代码
    【转载】windows phone7 学习笔记14——地理位置服务与反应性扩展框架
  • 原文地址:https://www.cnblogs.com/lxw0109/p/Initialization_and_class_loading.html
Copyright © 2011-2022 走看看