zoukankan      html  css  js  c++  java
  • JAVA程序执行顺序

    Mastiff类

    /**
     * 子类藏獒
     */
    public class Mastiff extends Dog {
        public Mastiff() {
            System.out.println("Mastiff");
        }
    
        {
            System.out.println("block");
        }
        static {
            System.out.println("static block");
        }
        
        public static void  main(String[] args){
            Mastiff mastiff=new Mastiff();
            
        }
    }

    DOG类

    /**
     *DOG父类
     */
    public class Dog {
        public Dog() {
            System.out.println("Dog");
        }
    }
    </span>

    运行结果为:

    static block
    Dog
    block
    Mastiff

    也就是说,在我们的程序中,实例化一个类对象的时候,运行顺序为:

    1.   静态块
    2.   父类构造器
    3.   本类中的块
    4.   本类的构造器 

    我们可以更进一步,如果在父类中也有块和静态块呢?

        DOG类改进后源码 

    /**
     *DOG父类
     */
    public class Dog {
        public Dog() {
            System.out.println("Dog");
        }
        static{
            System.out.println("super static block");
        }
        
        {
            System.out.println("super block");
        }
    }

       Mastiff改进后源码

    /**
     * 子类藏獒
     */
    public class Mastiff extends Dog {
        public Mastiff() {
            System.out.println("Mastiff");
        }
    
        {
            System.out.println("block");
            
        }
        static {
            System.out.println("static block");
        }
        
        public static void  main(String[] args){
            Mastiff mastiff=new Mastiff();        
        }
    }

    运行的结果为:

    super static block
    static block
    super block
    Dog
    block
    Mastiff

     也就是说此时的运行顺序为:

    1.    父类静态块
    2.    自身静态块
    3.    父类块
    4.    父类构造器
    5.    自身块
    6.    自身构造器 

      好了,知道了运行的顺序,那么这是为什么呢?

             这就要从JVM中类的装载机制和实例化机制开始说起,这里因为主题原因,先不讨论,有兴趣的同学可以自己查资料。

    我们再来讨论第二个问题,一个变量的值,它有可能在哪些地方确定呢??

    1. 从父类继承该值(包括:1.作为父类的成员变量已经赋值  2.在父类的块中赋值  3.在父类的构造器中赋值)
    2. 在构造器中对其进行赋值
    3. 在块中进行赋值
    4. 在方法调用中进行赋值

      现在假设在我们刚刚的例子中,有一个变量type,表示狗的品种

    /**
     *DOG父类
     */
    public class Dog {
        public String type="父类成员变量赋的值";
        public Dog() {
            System.out.println("父类构造器--type-->"+type);
            type="父类构造器赋的值";
                       System.out.println("父类构造器----type--->"+type);
        }
        
        {
            System.out.println("block---type--->"+type);
            type="父类块赋的值";
        }
    }
    /**
     * 子类藏獒
     */
    public class Mastiff extends Dog {
        public String type="成员变量赋的值";
        public Mastiff() {
            System.out.println("构造器---type--->"+type);
            type="构造器赋的值";
        }
        
        public void say(){
            System.out.println("say---type---->"+type);
        }
    
        {
            System.out.println("block---type--->"+type);
            type="块赋的值";
            
        }
        
        public static void  main(String[] args){
            Mastiff mastiff=new Mastiff();
            mastiff.say()</span><span style="font-size: medium;">;</span><span style="font-size: medium;">        
        }
    }

    执行结果如下:

    block---type--->父类成员变量赋的值
    父类构造器--type-->父类块赋的值
    父类构造器----type--->父类构造器赋的值
    block---type--->成员变量赋的值
    构造器---type--->块赋的值
    say---type---->构造器赋的值

    答案很明显,赋值顺序为:

    1. 父类成员变量赋值
    2. 父类块赋值
    3. 父类构造器赋值
    4. 自身成员变量赋值
    5. 自身块赋值
    6. 自身构造器赋值

     结合我们前面说的程序中的执行顺序,这个显然是很好理解的:

       1.成员变量赋值>>>块赋值>>>构造器赋值

       2.父类的块>>父类构造器>>自身块>>自身构造器

     又因为一个成员变量是不可能在静态变量中赋值的,而且又前面程序执行顺序可知

        静态块>>块

    所以,程序的赋值步骤为

      1. 父类的静态变量赋值
      2. 自身的静态变量赋值
      3. 父类成员变量赋值
      4. 父类块赋值
      5. 父类构造器赋值
      6. 自身成员变量赋值
      7. 自身块赋值
      8. 自身构造器赋值
  • 相关阅读:
    日期处理工具类
    本地存储
    wangeditor富文本编辑器的使用
    vue+axios 拦截器及使用
    angular引入bootstrap-slider无效问题
    解决vscode导致电脑卡顿问题
    vue组件
    vue框架制作TodoList
    vue框架
    jQuery系列09
  • 原文地址:https://www.cnblogs.com/chenlong-50954265/p/5555797.html
Copyright © 2011-2022 走看看