zoukankan      html  css  js  c++  java
  • 类初始化和实例初始化

    1、类初始化过程

      (1)一个类要创建实例需要先加载并初始化该类

        main()方法所在的类需要先加载和初始化 ---> 此类中main方法中为空 输出也为5 1 10 6

      (2)一个子类初始化要先初始化父类

      (3)一个类初始化就是执行<clinit>()方法 字节码文件中,<clinit>()方法由静态类变量显示赋值代码和静态代码块组成

        变量显示赋值代码和静态代码块从上到下执行

        <clinit>()方法只执行一次

    2、实例初始化过程

      (1)实例初始化就是执行<init>()方法

        <init>()方法可能重载有多个,有几个构造器就有几个<init>()方法

      (2)<init>()方法的首行是super()或者super(实例列表),即对应父类的<init>()方法 (最先执行)

         <init>()方法由 非静态类变量显示赋值代码和非静态代码块、对应构造器代码组成

         非静态变量显示赋值代码和非静态代码块从上到下执行,而对应的构造器代码最后执行(顺序执行)

        每次创建实例对象,调用对应的构造器,执行的就是 对应的<init>()方法    (最后执行)

    举例:

    public class Father {
     
        private int i = test();
        private static int j = method();
    
        static {
            System.out.println("1");
        }
    
        Father() {
            System.out.println("2");
        }
    
        {
            System.out.println("3");
        }
    
    
        public int test() {
            System.out.println("4");
            return 1;
        }
    
        public static int method() {
            System.out.println("5");
            return 1;
        }
    }  
     
    public class Son extends Father {
    
        private int i = test();
        private static int j = method();
    
        static {
            System.out.println("6");
        }
    
        Son() {
            //super();  写或者不写都存在,在子类的构造器中一定会调用父类的构造器
            System.out.println("7");
        }
    
        {
            System.out.println("8");
        }
    
        public int test() {
            System.out.println("9");
            return 1;
        }
    
        public static int method() {
            System.out.println("10");
            return 1;
        }
    
        public static void main(String[] args) {
            Son s1 = new Son();
            System.out.println();
            Son s2 = new Son();
        }
    
    }
    执行顺序: 
      1、先初始化父类 :
        <clinit>()方法
        (1)j = method()
        (2)静态代码块
        父类的静态类变量显示赋值代码和静态代码块 --> 5 1
      2、再初始化子类 :
        <clinit>()方法
          (1)j = method()
          (2)静态代码块
           子类的静态类变量显示赋值代码和静态代码块 --> 10 6
      3、子类的实例化方法
        (1)super() 父类的实例初始化 --> 9 3 2
        (2)i=test() --> 9
        (3)子类的非静态代码块 --> 8
       (4)子类的无参构造 -->7

        创建了两个Son()对象 因此子类的实例化方法执行两遍 --> 9 3 2 9 8 7

      子类的执行结果为:
    5 1 10 6 9 3 2 9 8 7
    9 3 2 9 8 7
      父类的初始化
        (1)j = method()
        (2)静态代码块
      父类的实例初始化
        (1)super()
        (2)i=test()
        (3)子类的非静态代码块
        (4)子类的无参构造
      注意:非静态方法前面其实一直有一个默认的对象this
         this在构造器或者<init>()方法中,他表示正在创建的对象,因此i=test()执行的是子类重写的代码(面向对象多态)
          这里的i=test()执行的是子类重写的test()方法

    3、方法的重写

      (1)、哪些方法不可以被重写
         final方法、静态方法、private等子类中不可见的方法
      (2)、对象的多态性
         子类如果重写了父类的方法,通过子类对象调用的一定是子类重写过的代码
         非静态方法默认的调用对象是this
         this对象在构造器或者<init>()方法中就是正在创建的对象

    4、overload和override的区别

    名词
    Overload方法的重载
    Override方法的重写
    位置
    同一个类中 
    在父子类中
    方法名
    必须相同
    必须相同
    形参列表
    必须不同
    必须相同
    返回值类型
    无关
    void和基数类型:一致;引用类型<=
    抛出的异常列表
    无关
    <=
    权限修饰符
    无关(建议一致)
    >=


       

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    Mac 安装实用开发软件和日常软件清单
    Docker zabbix-agent 监控 docker tomcat 多实例
    zabbix 组件监控概述
    实况8操作指南
    关于哲哲跳舞这件小事儿
    左耳听风笔记摘要(11-12)程序的异常处理
    左耳听风笔记摘要(07-10)推荐书单/Go/Docker
    从零开始的vue学习笔记(一)
    简述Spark工作流程
    opengl简单入门实例
  • 原文地址:https://www.cnblogs.com/lc0605/p/13293401.html
Copyright © 2011-2022 走看看