zoukankan      html  css  js  c++  java
  • 类的初始化变量和方法的执行顺序(父子类)

    static和没有static的区别
    *static的属性/方法在类加载时就已经做好准备,因此类名.就可以调用,与对象存在不存在无关。
    *非static的属性/方法隶属于对象,必须先创建对象,才能使用。
      static的方法中,不能使用非静态的属性或者方法,必须先创建对象,然后用对象.调用;而非static的方法中,可以直接使用静态的属性或方法。
    只有隶属于类(所有对象共享)的属性才能加static,static不能随便加。

    代码块 -- java允许直接用{}写代码,叫代码块。
    *写在类体中的代码块叫构造块,每创建一个对象,构造块都会被执行一次。
    *前面加static的构造块叫静态代码块,类加载时执行一次。

    对象创建的过程
     a.单个对象创建的执行过程
    (1)main()方法是程序的入口,使用new关键字创建对象时会在堆区申请内存空间;
    (2)若成员变量没有指定初始值,则采用默认初始化方式处理;
    (3)若成员变量进行显式初始化,则采用指定的初始值进行处理;
    (4)执行构造块中的代码,可以对成员变量进行赋值操作;
    (5)执行构造方法体中的代码,可以对成员变量进行再次赋值;
    (6)此时对象创建完毕,继续向下执行;

    b.子类对象创建的执行过程
    (1)main()方法是程序的入口,使用new关键字创建对象时会在堆区申请内存空间;
    (2)先加载父类再加载子类,因此先执行父类的静态代码块再执行子类的静态代码块;
    (3)执行父类的构造块和父类的构造方法体,此时内部的父类对象构造完毕;
    (4)执行子类的构造块和子类的构造方法体,此时子类对象构造完毕;
    (5)构造完毕后继续向下执行;

    执行顺序:(静态代码块和静态变量谁在前面就先执行谁)

    父类静态代变量、
    父类静态代码块、
    子类静态变量、
    子类静态代码块、
    父类非静态变量(父类实例成员变量)、
    父类构造函数、
    子类非静态变量(子类实例成员变量)、
    子类构造函数。

    代码示例

    package com.jdk.learn;
    
    public class ClassLoaderTest {
    
      public static void main(String[] args) {
        son sons=new son();
      }
    }
    
    class parent{
      private static int a=1;
      private static int b;
      private int c=initc();
      static {
        b=1;
        System.out.println("1.父类静态代码块:赋值b成功");
        System.out.println("1.父类静态代码块:a的值"+a);
      }
      int initc(){
        System.out.println("3.父类成员变量赋值:---> c的值"+c);
        this.c=12;
        System.out.println("3.父类成员变量赋值:---> c的值"+c);
        return c;
      }
      public parent(){
        System.out.println("4.父类构造方式开始执行---> a:"+a+",b:"+b);
        System.out.println("4.父类构造方式开始执行---> c:"+c);
       }
    }
    
    class son extends parent{
      private static int sa=1;
      private static int sb;
      private int sc=initc2();
      static {
        sb=1;
        System.out.println("2.子类静态代码块:赋值sb成功");
        System.out.println("2.子类静态代码块:sa的值"+sa);
      }
      int initc2(){
        System.out.println("5.子类成员变量赋值--->:sc的值"+sc);
        this.sc=12;
        return sc;
      }
      public son(){
        System.out.println("6.子类构造方式开始执行---> sa:"+sa+",sb:"+sb);
        System.out.println("6.子类构造方式开始执行---> sc:"+sc);
      }
    }

    执行结果:

    1.父类静态代码块:赋值b成功
    1.父类静态代码块:a的值1
    2.子类静态代码块:赋值sb成功
    2.子类静态代码块:sa的值1
    3.父类成员变量赋值:---> c的值0
    3.父类成员变量赋值:---> c的值12
    4.父类构造方式开始执行---> a:1,b:1
    4.父类构造方式开始执行---> c:12
    5.子类成员变量赋值--->:sc的值0
    6.子类构造方式开始执行---> sa:1,sb:1
    6.子类构造方式开始执行---> sc:12

    总结:

    当我们进行new实例化进行操作的时候,JVM都进行了什么操作呢?
    如果你看过深入理解jvm的话,应该会比较清楚,当我们使用new关键字进行实例化的时候,会进行如下几步处理:

    加载
    此阶段加载类的字节码信息到内存
    连接
    此阶段进行验证,分配默认值,符号引用转直接引用
    初始化
    为成员进行赋值等

    使用
    对实例进行操作比如sons.toString()

    对于我们的实例而言,我们只关注连接和初始化阶段即可。
    连接阶段我们按照类结构(成员变量(先),方法(后)等)的顺序(不是书写顺序),先对变量进行赋默认值0,对象的话为null。

    初始化的时候,就是对对象进行赋值,比如c执行initc()进行赋值。

    参考博客:https://blog.csdn.net/u014042066/article/details/77574956

  • 相关阅读:
    python高级函数六剑客
    测试工程师用到常用的git命令
    qing理解赋值,深浅拷贝的区别
    python设计模式之单例
    Python全栈之jQuery笔记
    畅谈python之单元测试框架-unittest
    浅析python之单元测试框架-unittest
    Python之日志处理(logging模块)
    Spring整理
    Spark学习笔记11面向对象编程
  • 原文地址:https://www.cnblogs.com/gwxppg/p/11189700.html
Copyright © 2011-2022 走看看