博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java类的初始化顺序
阅读量:5140 次
发布时间:2019-06-13

本文共 5941 字,大约阅读时间需要 19 分钟。

最近项目上工作强度还是蛮紧张的,技术还是公司框架自身封装好的(spring+mvc+mybatis+js+jquery+json+shiro+cacheEnable+swagger+ajax+反射等等几十项框架及插件),基础的原理还是没有脱离java的基础知识。今天抽个空把java类的初始化顺序整理一下(最近发现的一个规律,我之前用心总结的博客内容,在工作中用到的频次还是非常高的,所以好记性不如烂笔头,坚持总结、实践吧,骚年)。

一、构造器初始化

package com.edu;class Window {    Window(int marker) {        System.out.println("window(" + marker + ")");    }}class House {    Window w1 = new Window(1);    House() {        w3 = new Window(33);    }    Window w2 = new Window(2);    void f() {        System.out.println("f()");    }    Window w3 = new Window(3);}public class OrderOfInitialization {    public static void main(String[] args) {        House h = new House();        h.f();    }}结果:window(1)window(2)window(3)window(33)f()

①:初始化可以放在构造器内部;

②:House类在new对象时,会对内部的所有变量进行初始化,所以你看到的是先进行window(1)、window(2)、window(3)的初始化;

③:window(3)被初始化了两次

 

二、静态数据的初始化

package com.edu;/** * 静态数据的初始化 *  * @author tery * */class Bowl {    Bowl(int marker) {        System.out.println("Bowl(" + marker + ")");    }    void f1(int marker) {        System.out.println("f1(" + marker + ")");    }}class Table {    static Bowl bowl1 = new Bowl(1);    Table() {        System.out.println("Table");        bowl2.f1(1);    }    void f2(int marker) {        System.out.println("f2(" + marker + ")");    }    static Bowl bowl2 = new Bowl(2);}class CupBoard {    Bowl bowl3 = new Bowl(3);    static Bowl bowl4 = new Bowl(4);    CupBoard() {        System.out.println("CupBoard()");        bowl4.f1(2);    }    void f3(int marker) {        System.out.println("f3(" + marker + ")");    }    static Bowl bowl5 = new Bowl(5);}public class StaticInitialization {    public static void main(String[] args) {        System.out.println("Creating new CupBoard() in main");        new CupBoard();//        System.out.println("Creating new CupBoard() in main");//        new CupBoard();//        table.f2(1);//        cupboard.f3(1);    }//    static Table table=new Table();//    static CupBoard cupboard=new CupBoard();} 结果: Creating new CupBoard() in main Bowl(4) Bowl(5) Bowl(3) CupBoard() f1(2)
为了看清楚,把注释掉的代码逐步放开:
public class StaticInitialization {    public static void main(String[] args) {        System.out.println("Creating new CupBoard() in main");        new CupBoard();//        System.out.println("Creating new CupBoard() in main");//        new CupBoard();//        table.f2(1);//        cupboard.f3(1);    }    static Table table=new Table();//    static CupBoard cupboard=new CupBoard();}结果:Bowl(1)Bowl(2)Tablef1(1)Creating new CupBoard() in mainBowl(4)Bowl(5)Bowl(3)CupBoard()f1(2)

 

public class StaticInitialization {    public static void main(String[] args) {        System.out.println("Creating new CupBoard() in main");        new CupBoard();//        System.out.println("Creating new CupBoard() in main");//        new CupBoard();//        table.f2(1);//        cupboard.f3(1);    }    static Table table=new Table();    static CupBoard cupboard=new CupBoard();}结果:Bowl(1)Bowl(2)Tablef1(1)Bowl(4)Bowl(5)Bowl(3)CupBoard()f1(2)Creating new CupBoard() in mainBowl(3)CupBoard()f1(2)

 

public class StaticInitialization {    public static void main(String[] args) {        System.out.println("Creating new CupBoard() in main");        new CupBoard();        System.out.println("Creating new CupBoard() in main");        new CupBoard();//        table.f2(1);//        cupboard.f3(1);    }    static Table table=new Table();    static CupBoard cupboard=new CupBoard();}结果:Bowl(1)Bowl(2)Tablef1(1)Bowl(4)Bowl(5)Bowl(3)CupBoard()f1(2)Creating new CupBoard() in mainBowl(3)CupBoard()f1(2)Creating new CupBoard() in mainBowl(3)CupBoard()f1(2)

 

public class StaticInitialization {    public static void main(String[] args) {        System.out.println("Creating new CupBoard() in main");        new CupBoard();        System.out.println("Creating new CupBoard() in main");        new CupBoard();        table.f2(1);        cupboard.f3(1);    }    static Table table=new Table();    static CupBoard cupboard=new CupBoard();}结果:Bowl(1)Bowl(2)Tablef1(1)Bowl(4)Bowl(5)Bowl(3)CupBoard()f1(2)Creating new CupBoard() in mainBowl(3)CupBoard()f1(2)Creating new CupBoard() in mainBowl(3)CupBoard()f1(2)f2(1)f3(1)

 

小总结:

①无论创建多少个对象,静态数据都只占一份存储区域。static关键字不能应用于局部变量,因此它只能作用于域。如果一个域是静态的基本类型域,且没有对它进行初始化,那么它就会获得基本类型的标准初值,如果它是对象的引用,那么它的默认初始化的值就是null。

②初始化的顺序是先静态对象(如果它们尚未因前面的对象创建过程而被初始化),而后是非静态对象。

③要执行main()(静态方法),必须加载StaticInitialization类,紧接着其静态域table和cupboard被初始化,这将导致他们对应的类也被加载,并且由于它们也都包含静态的Bowl对象,因此Bowl随后也被加载。

三、.class创建对象

package com.edu;import java.util.Random;/** * .class属性的初始化 * @author tery * */class Initable{    Initable(){        System.out.println("Initable initial...");        }    static final String staticFinal="47";    static final int staticFinal2=ClassInitialization.rand.nextInt(1000);    static{        System.out.println("Initializing Initable");    }}class Initable2{    static int staticNonFinal=147;    static{        System.out.println("Initializing Initable2");    }}class Initable3{    static int staticNonFinal =74;    static {        System.out.println("Initializing Initable3");    }}public class ClassInitialization {public static Random rand=new Random(47);public static void main(String[] args){    Class initable=Initable.class;    System.out.println("After creating Initable ref");    System.out.println(Initable.staticFinal);    Initable a=new Initable();    System.out.println(Initable.staticFinal2);//    System.out.println(Initable2.staticNonFinal);//    System.out.println(Initable3.staticNonFinal);}}结果:After creating Initable ref47Initializing InitableInitable initial...258

为了使用类而准备的工作实际上包含三个步骤:

①加载,这是由类加载器执行的,该步骤将查找字节码(通常在classpath所指定的路径中查找,但这并非是必须的),并从这些字节码中创建一个Class对象。

②链接,在链接阶段将验证类中的字节码,为静态域分配存储空间,并且如果必须的话,将解析这个类创建的对其他类的所有引用。

③初始化,如果该类具有超类,则对其进行初始化,执行静态初始化器和静态初始化块。初始化被延迟到了对静态方法(构造器隐式地是静态的)或者非常数静态域进行首次引用时才执行。

④在打印Initable.staticFinal时属于调用常数静态域,即使加上Initable(){...}的构造方法,也不会执行,将int型改为String型也是同样的结果。

 

转载于:https://www.cnblogs.com/bossen/p/6145038.html

你可能感兴趣的文章
转载:在ASP.net 3.5中 用JSON序列化对象(两种方法)
查看>>
文件系统增量备份
查看>>
Linux下基于Xampp的TestLink的安装部署
查看>>
清華認證的流程
查看>>
【转】Java获取异常的堆栈信息到String的方式
查看>>
C++循环包含
查看>>
linux如何下解压windows下的.zip和.rar文件
查看>>
C# 多线程 Parallel.ForEach 和 ForEach 效率问题研究及理解
查看>>
《致橡树》-- 舒婷
查看>>
Ubuntu安装TFTP服务器
查看>>
ubuntu 10.10安装nginx+php的过程
查看>>
springmvc的DispatcherServlet拦截以及访问静态资源html、js、css 404问题
查看>>
怎样用Visual Basic6.0编写木马程序
查看>>
如何正确使用Cocoapods
查看>>
站立会议个人5
查看>>
Gulp--Less
查看>>
使用JSONPath
查看>>
嵌入式软件设计第9次实验报告
查看>>
morphia查询mongodb内嵌文档
查看>>
springcloud超时机制
查看>>