• Thinking in Java笔记之类及对象的初始化


    最近在看《Thinking in Java》这本书,之前一直对类及对象的初始化过程不太清楚,只是感到很模糊。看了这本书关于对象初始化的部分,终于搞明白了。

    废话不多说,先上两个例子,实例摘自 《Thinking in Java》。

    Test1:

     1 package com.westward;
     2 /**
     3  * @desc 《Thinking in Java》 Demo Page 115
     4  * */
     5 public class Demo14 {
     6 
     7     public static void main(String[] args) {
     8         // TODO Auto-generated method stub
     9         System.out.println("Inside main");//先初始化static成员变量和static代码块,然后非static成员变量和代码块,然后构造器,然后static main方法
    10         Cups.c1.f(99);//1
    11     }
    12     
    13     /*static Cups x=  new Cups();
    14     static Cups y=     new Cups();*///2
    15 }
    16 class Cup{
    17     public Cup(int marker) {
    18         System.out.println("Cup("+marker+")");
    19     }
    20     void f(int marker){
    21         System.out.println("f("+marker+")");
    22     }
    23 }
    24 class Cups{
    25     static Cup c1;
    26     static Cup c2;
    27     static{
    28         c1= new Cup(1);
    29         c2= new Cup(2);
    30     }
    31     Cups() {
    32         System.out.println("Cups()");// TODO Auto-generated constructor stub
    33     }
    34 }
    35 //run as:Cup(1)  Cup(2)  Cups() Cups() Inside main f(99)
    36 //注释掉tag2:Inside main Cup(1) Cup(2)  f(99) 

    我们将Cups类定义为下面这个,其初始化过程是一样的。即先初始化static成员变量,然后才static代码块。

     1 class Cups{
     2     static{
     3         c1= new Cup(1);
     4         c2= new Cup(2);
     5     }
     6     static Cup c1;
     7     static Cup c2;
     8     Cups() {
     9         System.out.println("Cups()");// TODO Auto-generated constructor stub
    10     }
    11 }

    Test2:

     1 package com.westward;
     2 
     3 /**
     4  * @desc 《Thinking in Java》 Demo Page 117
     5  * */
     6 public class Demo15 {
     7     Mug c1;
     8     Mug c2;
     9     {
    10         c1= new Mug(1);
    11         c2= new Mug(2);
    12         System.out.println("c1 & c2 initialized");
    13     }
    14     Demo15(){
    15         System.out.println("Mugs()");
    16     }
    17 
    18     public static void main(String[] args) {
    19         // TODO Auto-generated method stub
    20         System.out.println("Inside main()");
    21 //        Demo15 x= new Demo15();//2
    22     }
    23 
    24 }
    25 class Mug{
    26     Mug(int marker) {
    27         System.out.println("Mug("+marker+")");
    28     }
    29     void f(int marker){
    30         System.out.println("f("+marker+")");
    31     }
    32 }
    33 //Inside main() Mug(1) Mug(2) c1 & c2 initialized Mugs() 
    34 //注释掉tag2: Inside main()

    总结:从Test1和Test2,可以看出,首先,加载拥有主方法main的Demo14这个类,可以理解为jvm默认调用加载拥有main方法的Demo14这个类Demo14.class,然后初始化Demo14里的static修饰的成员变量,然后执行static修饰的代码块,然后执行main方法。main方法里(此处有三个出口):

      a.若定义一个类(比如Cups x),并new初始化这个对象Cups(),那么jvm就会加载Cups.class,然后初始化static成员变量,然后执行static修饰的代码块,然后非静态成员变量,然后非静态代码块,然后构造器。

      b.若直接调用类的静态方法或者静态类的静态成语,比如调用Cups.c1.f(99),那么jvm同样会加载Cups.class这个类,并且初始化。顺序为:初始化static成员变量,然后执行static修饰的代码块,然后非静态成员变量,然后非静态代码块,然后构造器。

      c.若main方法里既没有new对象,也没有调用类的静态成员或静态方法,没有类会被加载,所以没有类会被初始化,没有对象被初始化。

    注意:

      1.上面的初始化过程,我们假定静态成员,静态代码块,非静态成员,非静态代码块都存在的情况。若某一项不存在,那么顺序是不会变的,我们只需要从这个顺序列表中将其删除就OK。

      2.当我们new同一个类(Cups)的多个对象,或者调用Cups的静态方法或者静态成员多次,Cups.class只加载并且初始化一次。也就是说static成员变量和static静态代码块只初始化一次。非静态的对象的非静态成员变量、非静态代码块、构造器初始化次数则和new的次数相等。

      3.当我们new了Cups的一个对象,jvm载入Cups.class,并且初始化static修饰的...后,然后会为非静态成员默认初始化值[基本数据类型(int,byte,short,long为0,float,double为0.0,boolean为false,char为''),引用数据类型会将句柄初始化为null],然后若我们显示初始化此成员变量,就会执行显示初始化,然后执行非静态代码块,然后构造器。

  • 相关阅读:
    JS中this指向问题(const self = this)
    nuxt.js中koa2写接口顺序
    关于Vue中的slot-scope="scope"
    Nuxt.js 中设置 div的css的 height 为100%
    nuxt报错:[nuxt] store/index.js should export a method that returns a Vuex instance.
    解决element UI中当value初始值存在空值时select只显示初始值,不显示placeholder值
    CSS控制一行显示两个li
    原生JS实现列表子元素顺序反转的方法分析
    Javascript 字符串全排列组合方法实现
    mysql引擎
  • 原文地址:https://www.cnblogs.com/westward/p/5272693.html
Copyright © 2020-2023  润新知