Java类初始化执行流程解析

 测试代码:  

package com.test.ClassLaoderTest;

public  class test1 {
    public static String s_variable = "静态变量";
    public String init_variable = "公开的变量";
    private String p_variable = "私有的变量";
    //静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("静态代码块初始化执行了");
    }

    //初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("初始化代码块执行沦");
    }

    //构造方法
    public test1(){
        System.out.println("我是构造方法");
    }

    public static void main(String[] args) {

    }

}

  直接运行:

    

  main方法里面不做任何调用的情况下,自动调用的是静态代码块和静态变量

  (2)调用静态变量和静态方法:

    测试代码:    

package com.test.ClassLaoderTest;

public class test1 {
    public static String s_variable = "静态变量";
    public String init_variable = "公开的变量";
    private String p_variable = "私有的变量";
    //静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("静态代码块初始化执行了");
    }

    //初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("初始化代码块执行沦");
    }

    //构造方法
    public test1(){
        System.out.println("我是构造方法");
    }

    //静态方法
    public static void test1(){
        System.out.println("这是静态方法");
    }
    public static void main(String[] args) {
        System.out.println(test1.s_variable);
        test1.test1();
    }

}

  运行:

  

  结论:当我调用静态方法/静态变量时,只会家在静态代码块,其余的代码块/构造方法不会被加载

  (3)创建对象:

package com.test.ClassLaoderTest;

public class test1 {
    public static String s_variable = "静态变量";
    public String init_variable = "公开的变量";
    private String p_variable = "私有的变量";
    //静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("静态代码块初始化执行了");
    }

    //初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("初始化代码块执行了");
    }

    //构造方法
    public test1(){
        System.out.println("我是构造方法");
    }

    //静态方法
    public static void test1(){
        System.out.println("这是静态方法");
    }
    public static void main(String[] args) {
        test1 t1 = new test1();
    }

}

  运行结果:

    

  输出内容: 

静态变量
静态代码块初始化执行了
公开的变量
私有的变量
初始化代码块执行了
我是构造方法

  结论:当创建对象/实例化的时候,调用顺序:静态代码块->初始化代码->构造方法,最后执行的才是构造方法

  (4)有继承关系下的类初始化执行流程:

   环境:

    父类:

package com.test.ClassLaoderTest;

public class father {
    public static String s_variable = "父类静态变量";
    public String init_variable = "父类公开的变量";
    private String p_variable = "父类私有的变量";
    //父类静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("父类静态代码块初始化执行了");
    }

    //父类初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("父类初始化代码块执行了");
    }

    //构造方法
    public father(){
        System.out.println("我是父类构造方法");
    }

    //父类静态方法
    public static void test1(){
        System.out.println("这是父类静态方法");
    }
}

    test1.java:

    继承其父类father:

package com.test.ClassLaoderTest;

public class test1 extends father{
    public static String s_variable = "子类静态变量";
    public String init_variable = "子类公开的变量";
    private String p_variable = "子类私有的变量";
    //子类静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("子类静态代码块初始化执行了");
    }

    //子类初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("子类初始化代码块执行了");
    }

    //子类构造方法
    public test1(){
        System.out.println("我是子类构造方法");
    }

    //子类静态方法
    public static void test1(){
        System.out.println("这是子类静态方法");
    }

    public static void main(String[] args) {

    }
}

  main方法不做任何操作,运行:

    

 只要extends继承了,优先调用父类静态代码块

(5)有继承关系下的调用静态方法:

    修改子类即可:

package com.test.ClassLaoderTest;

public class test1 extends father{
    public static String s_variable = "子类静态变量";
    public String init_variable = "子类公开的变量";
    private String p_variable = "子类私有的变量";
    //子类静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("子类静态代码块初始化执行了");
    }

    //子类初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("子类初始化代码块执行了");
    }

    //子类构造方法
    public test1(){
        System.out.println("我是子类构造方法");
    }

    //子类静态方法
    public static void test1(){
        System.out.println("这是子类静态方法");
    }

    public static void main(String[] args) {
        test1.test1();
        father.test1();
    }
}

  运行:

      

  结果:

父类静态变量
父类静态代码块初始化执行了
子类静态变量
子类静态代码块初始化执行了
这是子类静态方法
这是父类静态方法

  main方法中,谁优先调用静态方法,就优先加载谁

 (6)有继承关系下的创建对象:

    代码:

package com.test.ClassLaoderTest;

public class test1 extends father{
    public static String s_variable = "子类静态变量";
    public String init_variable = "子类公开的变量";
    private String p_variable = "子类私有的变量";
    //子类静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("子类静态代码块初始化执行了");
    }

    //子类初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("子类初始化代码块执行了");
    }

    //子类构造方法
    public test1(){
        System.out.println("我是子类构造方法");
    }

    //子类静态方法
    public static void test1(){
        System.out.println("这是子类静态方法");
    }

    public static void main(String[] args) {
        test1 t1 =new test1();
    }
}

  运行:

   

  结果:

父类静态变量
父类静态代码块初始化执行了
子类静态变量
子类静态代码块初始化执行了
父类公开的变量
父类私有的变量
父类初始化代码块执行了
我是父类构造方法
子类公开的变量
子类私有的变量
子类初始化代码块执行了
我是子类构造方法

  结论:通过结果会发现,不管是子类还是父类静态代码块,静态代码块在哪里都是爸爸级别,最先加载的,当创建test1对象的时候,优先加载的是父类代码块,那么他的初始化执行流程如下:父类静态代码块>子类静态代码块>父类初始化代码块>父类构造方法>子类代码块>子类构造方法

(7) 有继承关系下的创建父类对象:

package com.test.ClassLaoderTest;

public class test1 extends father{
    public static String s_variable = "子类静态变量";
    public String init_variable = "子类公开的变量";
    private String p_variable = "子类私有的变量";
    //子类静态代码块
    static {
        System.out.println(s_variable);
        System.out.println("子类静态代码块初始化执行了");
    }

    //子类初始化代码块
    {
        System.out.println(init_variable);
        System.out.println(p_variable);
        System.out.println("子类初始化代码块执行了");
    }

    //子类构造方法
    public test1(){
        System.out.println("我是子类构造方法");
    }

    //子类静态方法
    public static void test1(){
        System.out.println("这是子类静态方法");
    }

    public static void main(String[] args) {
        father father = new father();
    }
}

 运行:

  

  结果:

父类静态变量
父类静态代码块初始化执行了
子类静态变量
子类静态代码块初始化执行了
父类公开的变量
父类私有的变量
父类初始化代码块执行了
我是父类构造方法

  结论:优先执行的是两个类的静态代码块,然后是父类型的代码块和构造方法,而子类的代码块和构造方法没有被执行是因为没有实例化子类,所以肯定是没有他的,那么只有在创建对象的时候,才会调用代码块和构造方法

到此这篇关于Java类初始化执行流程的文章就介绍到这了,更多相关Java类初始化执行流程内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java类继承关系中的初始化顺序实例详解

    本文实例讲述了Java类继承关系中的初始化顺序.分享给大家供大家参考,具体如下: Java类初始化的顺序经常让人犯迷糊,现在本文尝试着从JVM的角度,对Java非继承和继承关系中类的初始化顺序进行试验,尝试给出JVM角度的解释. 非继承关系中的初始化顺序 对于非继承关系,主类InitialOrderWithoutExtend中包含了静态成员变量(类变量)SampleClass 类的一个实例,普通成员变量SampleClass 类的2个实例(在程序中的顺序不一样)以及一个静态代码块,其中静态代码块

  • java类中元素初始化顺序详解

    复制代码 代码如下: public class Test4 {    @Test    public void test(){        child child = new child();    }} class parent{    public static String parentStaticField = "父类静态变量";    public String parentNormalField ="父类普通变量";    static {      

  • Java类加载初始化的过程及顺序

    Java类的加载说明 Java类的编译代码都存在于它自己的独立文件中(class),该文件只在需要使用程序代码时才会被加载. 类加载在创建类的第一个对象时发生,但当访问static域或static方法时,也会发生加载. 构造器也是static方法,尽管static关键字没有显式写出,故可进一步说,类是在任何static成员被访问时加载的. 示例说明加载过程 示例源于<Java编程思想> //父类 public class SuperClass { protected int super_a;

  • 简单了解java类的初始化以及类的实例化

    前言 上一篇我们知道了一个类的生命周期是:加载->验证->准备->解析->初始化->使用->卸载. 当初始化完成以后,一个类所有的类变量(被static修饰的变量)都被赋值.但是未被static修饰的成员变量又是何时被赋值的呢? 一个类何时会被初始化 一个类何时被初始化可以分为以下几类: 1.创建类的实例(new). 2.访问某个类或接口的静态变量,或者对该静态变量赋值. 3.调用类的静态方法. 4.通过反射方式执行以上三种行为. 5.初始化子类的时候,会触发父类的初始

  • Java类初始化和实例化中的2个“雷区”

    在考虑类初始化时,我们都知道进行子类初始化时,如果父类没有初始化要先初始化子类.然而事情并没有一句话这么简单. 首先看看Java中初始化触发的条件: (1)在使用new实例化对象,访问静态数据和方法时,也就是遇到指令:new,getstatic/putstatic和invokestatic时: (2)使用反射对类进行调用时: (3)当初始化一个类时,父类如果没有进行初始化,先触发父类的初始化: (4)执行入口main方法所在的类: (5)JDK1.7动态语言支持中方法句柄所在的类,如果没有初始化

  • Java类初始化执行流程解析

    测试代码: package com.test.ClassLaoderTest; public class test1 { public static String s_variable = "静态变量"; public String init_variable = "公开的变量"; private String p_variable = "私有的变量"; //静态代码块 static { System.out.println(s_variable

  • Java类初始化时机测试方法解析

    <clinit>()方法 Java 类加载的初始化过程中,编译器按语句在源文件中出现的顺序,依次自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并产生方法. 如果类中没有静态语句和静态代码块,那可以不生成<clinit>() 方法. 并且 <clinit>() 不需要显式调用父类(接口除外,接口不需要调用父接口的初始化方法,只有使用到父接口中的静态变量时才需要调用)的初始化方法 <clinit>(),虚拟机会保证在子类的 <clinit>

  • Java字段初始化的规律解析

    这篇文章主要介绍了Java字段初始化的规律解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在Java中定义一个类后,有三种方式可以对其中的变量进行初始化:直接输入,初始化块,构造函数. 而对于这三者的优先级,其应该是: 1.类的构造函数(构造方法): 当创建一个对象时,其构造函数就会自动调用.构造方法必须与类名相同,无返回值. 如果程序员没有定义一个构造函数时,系统会自动定义一个不含参数的"默认构造函数",在自定义构造函数后就不再

  • 通过实例解析Java类初始化和实例初始化

    一.背景: 存在类Father和类Son,其中类Son继承了Father类. 1.父类Father代码 2.子类Son代码 *初始化包括? 成员变量赋初值.代码块.构造器 注意方法是被调用的,有人调用它它才执行相应的东西. 二.类初始化 在一开始,注释掉main方法中的代码,执行结果如下. 类初始化: 1.创建实例需要先加载并初始化该类 此处main方法所在的类需要先加载并初始化 2.子类初始化要先初始化其父类 3.类初始化即是执行clinit(ClassInit)方法 A.(静态!)分为 静态

  • iOS直播类APP开发流程解析

    本文为大家分享了iOS直播类APP开发流程,供大家参考,具体内容如下 一 . 音视频处理的一般流程: 数据采集→数据编码→数据传输(流媒体服务器) →解码数据→播放显示 1.数据采集: 摄像机及拾音器收集视频及音频数据,此时得到的为原始数据 涉及技术或协议: 摄像机:CCD.CMOS 拾音器:声电转换装置(咪头).音频放大电路 2.数据编码: 使用相关硬件或软件对音视频原始数据进行编码处理(数字化)及加工(如音视频混合.打包封装等),得到可用的音视频数据 涉及技术或协议: 编码方式:CBR.VB

  • Java注释代码执行方法解析

    直接上代码: @Test public void testUnicode() { String a = "Hello"; // \u000d a="world"; System.out.println(a); // \u000a a="hello world!"; System.out.println(a); } 猜一猜,最后会输出什么? world hello world! 是的,没看错,那二行看似"注释掉的代码",被执行了

  • java高并发ThreadPoolExecutor类解析线程池执行流程

    目录 摘要 核心逻辑概述 execute(Runnable)方法 addWorker(Runnable, boolean)方法 addWorkerFailed(Worker)方法 拒绝策略 摘要 ThreadPoolExecutor是Java线程池中最核心的类之一,它能够保证线程池按照正常的业务逻辑执行任务,并通过原子方式更新线程池每个阶段的状态. 今天,我们通过ThreadPoolExecutor类的源码深度解析线程池执行任务的核心流程,小伙伴们最好是打开IDEA,按照冰河说的步骤,调试下Th

  • Java初始化块及执行过程解析

    问题:Java对象初始化方式主要有哪几种?分别是什么? 针对上面的问题,想必大家脑海中首先浮现出的答案是构造器,没错,构造器是Java中常用的对象初始化方式. 还有一种与构造器作用非常相似的是初始化块,它可以对Java对象进行初始化操作.下面主要阐述Java的初始化块及执行过程. Java初始化块其实是Java类的成员之一,其语法格式如下: [修饰符]{ //初始化块的可执行代码 ... } 初始化块的修饰符只能是static,使用static修饰符的初始化块称为静态初始化块,后面会介绍到. 下

随机推荐