美文网首页
Java类加载机制的理解浅析

Java类加载机制的理解浅析

作者: 路漫漫其修远兮Wzt | 来源:发表于2017-11-15 10:11 被阅读98次

    从今日头条上看到了一道考察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

    相关文章

      网友评论

          本文标题:Java类加载机制的理解浅析

          本文链接:https://www.haomeiwen.com/subject/wjfcvxtx.html