java 类与非静态内部类、静态内部类、父类与子类 各代码块的加载顺序

最近面试被问到外部类与静态内部类 各代码块的加载顺序,思考许久,最终回答的不理想,事后思考再三,还是对这块的加载顺序理解的不透彻,借此机会,重新认识并做了一些demo,俗话说“实践出真知”,以下是具体的总结和demo,奉上。

1、同一个类中各代码块的加载顺序: 静态代码块 -> 构造代码块 ->  构造方法 -> 具体方法     

public class Main {
    /**静态代码块*/
    static {
        System.out.println("static code block.");
    }

    /**构造代码块*/ {
        System.out.println("construct code block");
    }

    /** 构造方法 */
    public Main() {
        System.out.println("class construct");
    }

    public static void main(String[] args) {
        System.out.println("main exec");
        Main main = new Main();
    }
}
static code block.
main method
construct code block
class construct

2、外部类与其非静态内部类  各代码块的加载顺序:静态代码块(外部类) -> main 方法 -> 构造方法块(外部类) -> 构造(方法)-> 构造方法块(内部类) -> 构造方法(内部类)

    注意:①、上面的执行顺序,在创建内部类的时候才会看到,如果只创建外部类的对象,非静态内部类的的各代码块及构造方法不会被调用

               ②、外部类不能访问内部类的成员变量和方法, 但是内部类可以访问外部类的

               ③、非静态内部类,不允许出现静态变量、静态代码块,但可以有构造方法块

               ④、非静态内部类必须寄存在一个外部类对象里。因此,如果有一个非静态内部类对象那么一定存在对应的外部类对象。非静态内部类对象单独属于外部类的某个对象

public class ClassLoadWithInnerClassTest {
    /**静态代码块*/
    static {
        System.out.println("static code block.");
    }

    /**构造代码块*/
    {
        System.out.println("construct code block");
    }

    /** 构造方法 */
    public ClassLoadWithInnerClassTest() {
        System.out.println("class construct");
    }

    /** 普通方法 */
    void doMethod() {
        System.out.println("static method is invoked.");
        InternalClass internalClass = new InternalClass();
    }

    InternalClass createInternalClass(){
        return new InternalClass();
    }

    public class InternalClass {
        {
            System.out.println("inner class construct code block.");
        }

        public InternalClass() {
            System.out.println("inner class construct.");
        }

        void doMethod() {
            System.out.println("inner static method is invoked.");
        }

        void invikeOutMethod(){
            ClassLoadWithInnerClassTest.this.doMethod();
        }
    }


    public static void main(String[] args) {
        System.out.println("main method ");
        ClassLoadWithInnerClassTest classTest = new ClassLoadWithInnerClassTest();
        classTest.createInternalClass();
    }

}
static code block.
main method 
construct code block
class construct
inner class construct code block.
inner class construct.

3、外部类与其静态内部类  各代码块的加载顺序:静态代码块(外部类) -> main 方法 -> 构造方法块(外部类) -> 构造(方法)-> 构造方法块(内部类) -> 构造方法(内部类)

        跟2 的执行顺序一致,不同的是:

        ①、外部类可以访问静态内部类的静态属性及方法

        ②、静态内部类,可以有静态属性、方法及静态代码块

        ③、当创建静态内部类或静态属性、方法被访问时,它的静态代码块才会被执行  

public class ClassLoadWithStaticInnerClassTest {

    //静态代码块
    static {
        System.out.println("static code block.");
    }

    //构造代码款
    {
        System.out.println("construct code block");
    }

    /** 构造方法 */
    public ClassLoadWithStaticInnerClassTest() {
        System.out.println("class construct create");
    }

    /** 普通方法 */
    void doMethod() {
        System.out.println("static method is invoked.");
        InternalClass.doMethod();
    }

    InternalClass createInternalClass(){
        return new InternalClass();
    }

    public static class InternalClass {
        static {
            System.out.println("internal class static code block.");
        }

        {
            System.out.println("internal class construct code block.");
        }

        public InternalClass() {
            System.out.println("internal class construct.");
        }

        public static void doMethod(){
            System.out.println("inner static method ");
        }
    }


    public static void main(String[] args) {
        System.out.println("main method exec");
        ClassLoadWithStaticInnerClassTest classTest = new ClassLoadWithStaticInnerClassTest();
        classTest.doMethod();
        System.out.println("————————————————————————————");
        ClassLoadWithStaticInnerClassTest.InternalClass internalClass = new ClassLoadWithStaticInnerClassTest.InternalClass();
    }
static code block.
main method exec
construct code block
class construct create
static method is invoked.
internal class static code block.
inner static method 
————————————————————————————
internal class construct code block.
internal class construct.

4、 父类 及其子类的各代码块的加载顺序: 静态代码块(父类) -> 静态代码块(子类) -> main 方法 -> 构造代码块(父类) -> 构造方法(父类)-> 构造代码块(子类) -> 构造方法(子类) -> 静态代码块(父类静态内部类) -> 构造方法块(父类静态内部类) -> 构造方法(父类静态内部类)

public class SupperClass {

    //静态代码块
    static {
        System.out.println("supper static code block.");
    }

    //构造代码款
    {
        System.out.println("supper construct code block");
    }

    /** 构造方法 */
    public SupperClass() {
        System.out.println("supper class construct create");
    }

    /** 普通方法 */
    void doMethod() {
        System.out.println("supper static method is invoked.");
        InternalClass internalClass = new InternalClass();
    }

    InternalClass createInternalClass(){
        return new InternalClass();
    }

    public static class InternalClass {
        static {
            System.out.println("supper internal class static code block.");
        }

        {
            System.out.println("supper internal class construct code block.");
        }

        public InternalClass() {
            System.out.println("supper internal class construct create.");
        }

        void doMethod() {
            System.out.println("supper static method is invoked.");
        }
    }

 

public class SubClass extends SupperClass{

    //静态代码块
    static {
        System.out.println("sub class static code block.");
    }

    //构造代码款
    {
        System.out.println("sub class construct code block");
    }

    /** 构造方法 */
    public SubClass() {
        System.out.println("sub class construct create");
    }

    /** 普通方法 */
    @Override
    void doMethod() {
        System.out.println("sub class static method is invoked.");
        InternalClass internalClass = new InternalClass();
    }

    @Override
    InternalClass createInternalClass(){
        return new InternalClass();
    }


    public static void main(String[] args) {
        System.out.println("main method exec");
        SubClass classTest = new SubClass();
        classTest.createInternalClass();
    }
supper static code block.
sub class static code block.
main method exec
supper construct code block
supper class construct create
sub class construct code block
sub class construct create
supper internal class static code block.
supper internal class construct code block.
supper internal class construct create.

完毕!!!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值