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. 导出类初始化:先是导出类的非静态成员初始化,然后是导出类构造器的执行

  • 相关阅读:
    轻量级的Web服务器Nginx0.9.0 开发版发布 狼人:
    微软发布Silverlight 5 Beta新特性 狼人:
    TechCrunch新闻评论:Flash耗电问题严重 狼人:
    IE9是最佳浏览器? 狼人:
    Silverlight面向客户端,HTML5面向Web 狼人:
    Silverlight 结构分析 狼人:
    HTML5是否已经准备好了?仍在W3C层层审核当中 狼人:
    Adobe驳斥Flash过度耗电论 称HTML5更耗电 狼人:
    Silverlight 5即将来临 狼人:
    运行控制[置顶] 有趣的编程控制自己电脑的CPU
  • 原文地址:https://www.cnblogs.com/lxw0109/p/Initialization_and_class_loading.html
Copyright © 2011-2022 走看看