Java类加载机制的理解浅析

从今日头条上看到了一道考察Java类加载机制的基础题,感觉不错,只是没有看到答案,所以自己手动敲了一下代码,现将其整理如下:

题目

1.父类A、子类B(继承自父类A)、程序入口类C
public class HelloA {

    public HelloA() {
        System.out.println("父类A 构造方法");
    }
    
    { System.out.println("父类A 构造代码块"); }
    
    static { System.out.println("父类A 静态方法"); }
}

public class HelloB extends HelloA {
    
    public HelloB() {
        System.out.println("子类B 构造方法");
    }
    
    { System.out.println("子类B 构造代码块"); }
    
    static { System.out.println("子类B 静态方法"); }
}

//程序入口类
public class HelloC {

    public static void main(String[] args){
        
        System.out.println("-----------main start-----------");
        new HelloB();
        System.out.println("-----------main end-------------");
    }
}

运行结果如下:

-----------main start-----------
父类A 静态方法
子类B 静态方法
父类A 构造代码块
父类A 构造方法
子类B 构造代码块
子类B 构造方法
-----------main end-------------

2.父类A、子类B(继承自父类A),程序入口在B类中

public class HelloA {

    public HelloA() {
        System.out.println("HelloA");
    }
    
    { System.out.println("I'm A class."); }
    
    static { System.out.println("Static A"); }
}

public class HelloB extends HelloA {
    
    public HelloB() {
        System.out.println("HelloB");
    }
    
    { System.out.println("I'm B class."); }
    
    static { System.out.println("Static B"); }

    public static void main(String[] args){
        
        System.out.println("-----------main start-----------");
        new HelloB();
        System.out.println("-----------main end-------------");
    }
}

运行结果如下:

父类A 静态方法
子类B 静态方法
-----------main start-----------
父类A 构造代码块
父类A 构造方法
子类B 构造代码块
子类B 构造方法
-----------main end-------------

3.父类A、子类B(继承自父类A),程序入口在A类中

public class HelloA {

    public HelloA() {
        System.out.println("HelloA");
    }
    
    { System.out.println("I'm A class."); }
    
    static { System.out.println("Static A"); }

    public static void main(String[] args){
        
        System.out.println("-----------main start-----------");
        new HelloB();
        System.out.println("-----------main end-------------");
    }
}

public class HelloB extends HelloA {
    
    public HelloB() {
        System.out.println("HelloB");
    }
    
    { System.out.println("I'm B class."); }
    
    static { System.out.println("Static B"); }
}

运行结果如下:

父类A 静态方法
-----------main start-----------
子类B 静态方法
父类A 构造代码块
父类A 构造方法
子类B 构造代码块
子类B 构造方法
-----------main end-------------

简单总结:

1.实例化子类的时候
(1)若此类未被加载过,首先加载是父类的类对象,然后加载子类的类对象,接着实例化父类,最后实例化子类;
(2)若此类被加载过,不再加载父类和子类的类对象。

2.接下来是加载顺序
(1)当加载类对象时,首先初始化静态属性,然后执行静态块;
(2)当实例化对象时,首先执行构造块(直接写在类中的代码块),然后执行构造方法。
(3)如果存在多个静态块,各静态块之间执行的顺序按代码先后;如果存在多个静态属性,各静态属性初始化的顺序按代码先后。
(4)属性、构造块(也就是上面的实例块)、构造方法之间的执行顺序(但构造块一定会在构造方法前执行),也是按代码的先后顺序。
3.还要注意入口函数位置、类的执行顺序;

本人java小白,有错误还请指出,共同学习...

参考资料:
(1)Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序
https://www.cnblogs.com/chihirotan/p/6043442.html
(2)一道网易Java工程师面试题看出你对Java类加载机制的理解深浅
http://url.cn/57lX6cG

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,767评论 18 399
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,688评论 0 11
  • Win7下如何打开DOS控制台? a:开始--所有程序--附件--命令提示符 b:开始--搜索程序和文件--cmd...
    逍遥叹6阅读 1,614评论 4 12
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 1,267评论 0 2
  • 前三篇文章,我们介绍了新闻写作的内容选取的技巧和方法,获得了很多朋友的关注。这种共同进步让我们倍感荣幸和高兴。 那...
    高校传媒与写作协会阅读 542评论 0 6