精华内容
下载资源
问答
  • 本篇文章是对java中子类继承父类,程序运行顺序进行了详细的分析介绍,需要的朋友参考下
  • Java继承类执行顺序

    千次阅读 2016-09-06 14:14:36
    Java继承类执行顺序

    最近答了一些笔试题,发现继承类的执行顺序这种题基本谁家都问。下面是结合网上其他总结后,自己做了更细致的试验。第一篇博文,话还说不太明白,但是我觉得如果想成为一名好的攻城狮就应该好好写博客,把话说明白了,自己也才能更清楚。我这人不够细心,还好还有点责任心,希望通过写博客来改掉这个坏毛病。

    class People {
        int age;
        String name;
    
        static{
            System.out.println("2、父类的静态代码段");
        }
    
        People(){
            System.out.println("5、父类的无参构造方法");
        }
    
        People(int age , String name){
            this.age = age;
            this.name = name;
            System.out.println("5、父类的有参构造方法");
        }
    
        void eat(){
            System.out.println("8、父类的方法:吃饭!");
        }
    
        {
            System.out.println("4、父类的非静态代码段");
        }
    
        void drink(){
            System.out.println("8、父类的方法:喝水!");
        }
    }
    
    class Student extends People {
        int grade;
        {
            System.out.println("6、子类的非静态代码段");
        }
    
        static{
            System.out.println("3、子类的静态代码段");
        }
    
        Student(){
            //super();运行子类的构造函数前,要先运行父类的构造函数,此处省略默认执行的父类构造函数
            System.out.println("7、子类的无参构造方法");
        }
    
        Student(int age , String name , int grade){
    
            super(age,name);//运行子类的有参构造函数前,要先运行父类的有参构造函数,若父类无有参的构造函数,则执行父类的无参的构造函数
            this.grade = grade;
            System.out.println("7、子类的有参构造方法 " + name + "," + age + "岁," + grade + "年级。");
        }
    
        void eat(){
            System.out.println("8、子类的方法:吃饭!");
        }
    }
    
    public class ExtendedClassOrder {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            System.out.println("1、main()方法");
    
            Student s1 = new Student();
            s1.eat();
            s1.drink();
            System.out.println("---------------");
            Student s2 = new Student(19, "LEE", 1);
            s2.eat();
            System.out.println("---------------");
            People s3 = new Student();
            s3.drink();
        }
    }

    执行结果:
    1、main()方法
    2、父类的静态代码段
    3、子类的静态代码段
    4、父类的非静态代码段
    5、父类的无参构造方法
    6、子类的非静态代码段
    7、子类的无参构造方法
    8、子类的方法:吃饭!
    8、父类的方法:喝水!
    ---------------
    4、父类的非静态代码段
    5、父类的有参构造方法
    6、子类的非静态代码段
    7、子类的有参构造方法 LEE,19岁,1年级。
    8、子类的方法:吃饭!
    ---------------
    4、父类的非静态代码段
    5、父类的无参构造方法
    6、子类的非静态代码段
    7、子类的无参构造方法
    8、父类的方法:喝水!

    试验发现:

    • 父类的方法都先于子类的执行,只有子类的静态代码段会紧跟父类的静态代码段先执行。 静态的代码段只执行一次。
    • 非静态的代码段每次创建对象的时候都会执行一次,且先于构造方法执行。
    • 子类执行普通方法是,如果是子类覆盖了父类的方法则执行子类方法,如果没有覆盖则执行父类方法。
    展开全文
  • Java类加载执行顺序

    千次阅读 2020-05-22 18:20:26
    加载是Java程序运行的第一步,研究的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行。研究加载机制的第二个目的是让程序能动态的控制加载,比如热部署等,提高程序的灵活性和适应性...

    当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现这个类进行初始化

    一、加载

    加载,是指Java虚拟机查找字节流(查找.class文件),并且根据字节流创建java.lang.Class对象的过程。这个过程,将类的.class文件中的二进制数据读入内存,放在运行时区域的方法区内。然后在堆中创建java.lang.Class对象,用来封装类在方法区的数据结构

    类加载阶段:

    (1)Java虚拟机将.class文件读入内存,并为之创建一个Class对象。
    (2)任何类被使用时系统都会为其创建一个且仅有一个Class对象。
    (3)这个Class对象描述了这个类创建出来的对象的所有信息,比如有哪些构造方法,都有哪些成员方法,都有哪些成员变量等。

    Student类加载过程图示:
    在这里插入图片描述
    二、连接

    连接包括验证、准备以及解析三个阶段。

    (1)验证阶段。主要的目的是确保被加载的类(.class文件的字节流)满足Java虚拟机规范,不会造成安全错误。
    (2)准备阶段。负责为类的静态成员分配内存,并设置默认初始值。
    (3)解析阶段。将类的二进制数据中的符号引用替换为直接引用。
    说明:

    符号引用。即一个字符串,但是这个字符串给出了一些能够唯一性识别一个方法,一个变量,一个类的相关信息。

    直接引用。可以理解为一个内存地址,或者一个偏移量。比如类方法,类变量的直接引用是指向方法区的指针;而实例方法,实例变量的直接引用则是从实例的头指针开始算起到这个实例变量位置的偏移量。

    举个例子来说,现在调用方法hello(),这个方法的地址是0xaabbccdd,那么hello就是符号引用,0xaabbccdd就是直接引用。

    在解析阶段,虚拟机会把所有的类名,方法名,字段名这些符号引用替换为具体的内存地址或偏移量,也就是直接引用。

    三、初始化

    初始化,则是为标记为常量值的字段赋值的过程。换句话说,只对static修饰的变量或语句块进行初始化。

    如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。
    如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行。

    静态代码块>初始化属性值>普通代码块>构造方法
    注:构造方法最后执行。

    注意:
    类加载过程只是一个类生命周期的一部分,在其前,有编译的过程,只有对源代码编译之后,才能获得能够被虚拟机加载的字节码文件;在其后还有具体的类使用过程,当使用完成之后,还会在方法区垃圾回收的过程中进行卸载(垃圾回收)。

    四、类加载器
    虚拟机设计团队把加载动作放到JVM外部实现,以便让应用程序决定如何获取所需的类。

    1、Java语言系统自带有三个类加载器
    Bootstrap ClassLoader :最顶层的加载类,主要加载核心类库,也就是我们环境变量下面%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等。另外需要注意的是可以通过启动jvm时指定-Xbootclasspath和路径来改变Bootstrap ClassLoader的加载目录。比如java -Xbootclasspath/a:path被指定的文件追加到默认的bootstrap路径中。我们可以打开我的电脑,在上面的目录下查看,看看这些jar包是不是存在于这个目录。
    Extention ClassLoader :扩展的类加载器,加载目录%JRE_HOME%\lib\ext目录下的jar包和class文件。还可以加载-D java.ext.dirs选项指定的目录。
    Appclass Loader:也称为SystemAppClass。 加载当前应用的classpath的所有类。
    我们看到java为我们提供了三个类加载器,应用程序都是由这三种类加载器互相配合进行加载的,如果有必要,我们还可以加入自定义的类加载器。这三种类加载器的加载顺序
    Bootstrap ClassLoader > Extention ClassLoader > Appclass Loader
    层次关系如下图所示
    在这里插入图片描述
    代码验证如下:
    在这里插入图片描述
    从上面的结果可以看出,并没有获取到ExtClassLoader的父Loader,原因是Bootstrap Loader(引导类加载器)是用C语言实现的,找不到一个确定的返回父Loader的方式,于是就返回null。

    2、类加载的三种方式
    认识了这三种类加载器,接下来我们看看类加载的三种方式。

    (1)通过命令行启动应用时由JVM初始化加载含有main()方法的主类。
    (2)通过Class.forName()方法动态加载,会默认执行初始化块(static{}),但是Class.forName(name,initialize,loader)中的initialze可指定是否要执行初始化块。
    (3)通过ClassLoader.loadClass()方法动态加载,不会执行初始化块

    3、双亲委派原则

    他的工作流程是: 当一个类加载器收到类加载任务,会先交给其父类加载器去完成,因此最终加载任务都会传递到顶层的启动类加载器,只有当父类加载器无法完成加载任务时,才会尝试执行加载任务

    采用双亲委派的一个好处是比如加载位于rt.jar包中的类java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个Object对象。
    双亲委派原则归纳一下就是:

    1)沙箱安全机制:自己写的java.lang.String.class类不会被加载,这样便可以防止核心API库被随意篡改
    2)避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次,保证被加载类的唯一性

    4、自定义类加载器

    自定义类加载器的两种方式:

    (1)遵守双亲委派模型:继承ClassLoader,重写findClass()方法。
    (2)破坏双亲委派模型:继承ClassLoader,重写loadClass()方法。 通常我们推荐采用第一种方法自定义类加载器,最大程度上的遵守双亲委派模型。

    参考文章:
    https://www.cnblogs.com/luohanguo/p/9469851.html
    https://www.jianshu.com/p/202f6abb229c

    展开全文
  • 执行顺序,父类中的静态代码块,子类中的静态代码块,父类中的代码块,父类中的无参构造方法,子类中的代码块,子类中的无参构造方法   如查子类有参的构造函数 new Children(“a”,"b"); 执行顺序:...

    父类 

     子类

    1.如果子类不实例化

    输入的是父类中的静态代码块,子类中的静态代码块

    如查子类无参的构造函数

    new Children();

    执行顺序,父类中的静态代码块,子类中的静态代码块,父类中的代码块,父类中的无参构造方法,子类中的代码块,子类中的无参构造方法

     

    如查子类有参的构造函数

    new Children(“a”,"b");

    执行顺序:父类中的静态代码块,子类中的静态代码块,父类中代码块,父类中无参的构造方法,子类中代码块,子类中有参的构造方法

    如果子类中调用父类中有参的构造方法,需放在在方法第一句

    public Children(){

    super("pa","pb");

     }

    则不再执行父类中无参的构造方法,取代为有参的构造方法

     

     

    展开全文
  • java 中 各部分的执行顺序

    千次阅读 2018-08-28 11:36:21
    package com.fjf.test.classloadoreder; /** * * *参考:... * 测试加载的顺序 * @author fjf * 2018年8月28日 11:07:16 * * 若还未被加载 ...

    package com.fjf.test.classloadoreder;

    /**
    *
    *
    *参考:https://blog.csdn.net/anticlql/article/details/74011018 (自己做了点修改)
    * 测试类加载的顺序
    * @author fjf
    * 2018年8月28日 11:07:16
    *
    *
    若类还未被加载
    1. 先执行父类的静态代码块和静态变量初始化,并且静态代码块和静态变量的执行顺序只跟代码中出现的顺序有关。
    2. 执行子类的静态代码块和静态变量初始化。
    3. 执行父类的实例变量初始化
    4. 执行父类的构造函数
    5. 执行子类的实例变量初始化
    6. 执行子类的构造函数

    若类已经加载
    则静态代码块和静态变量就不用重复执行,再创建类对象时,只执行与实例相关的变量初始化和构造方法
    *
    *
    * :静态块(静态变量)→成员变量→构造方法
    *
    */

    “`
    class ClassA{
    static{
    System.out.println(“In ClassA Static”);
    }
    public ClassA(){
    System.out.println(“ClassA()”);
    }
    }

    class ClassB{
        static{
            System.out.println("In ClassB Static");
        }
    
        ClassB1 b1 = new ClassB1();
    
        public ClassB(){
            System.out.println("ClassB()");
        }
    }
    
    class ClassC extends ClassB{
        static{
            System.out.println("In ClassC Static");
        }
        ClassC1 c1 = new ClassC1();
        public ClassC(){
            System.out.println("ClassC()");
        }
    }
    
    class MyCLasss{
        static ClassA ca = new ClassA();
        ClassC cc = new ClassC();
        static{
            System.out.println("In MyCLasss Static");
        }
        public MyCLasss(){
            System.out.println("MyCLasss()");
        }
    }
    
    
    class ClassB1{
        public ClassB1(){
            System.out.println("ClassB1()");
        }
    }
    
    class ClassC1{
        public ClassC1(){
            System.out.println("ClassC1()");
        }
    }
    
    public class TestMain {
        public static void main(String[] args){
            MyCLasss mc1 =  new MyCLasss();
            System.out.println("-------------------");
            MyCLasss mc2 =  new MyCLasss();
        }
    }
    

    “`————————————
    运行结果:
    这里写图片描述

    可先自己推演一边 再对下执行结果:

    这里写图片描述

    展开全文
  • java中子类继承父类程序执行顺序

    千次阅读 2018-01-15 15:35:49
    Java中,new一个的对象,里面的静态代码块、非静态代码、无参构造方法、有参构造方法、的一般方法等部分,它们的执行顺序相对来说比较简单,用程序也很容易验证。比如新建一个测试父类。 public class ...
  • 原文地址:https://blog.csdn.net/SnailMann/article/details/78665874得到的结论是:先执行父类构造函数,再执行子类构造函数父类:Animal.java[java] view plain copypackage extendsdemo; public class ...
  • java 实例化执行顺序

    千次阅读 2019-06-01 23:13:53
    java 实例化执行顺序分析。示例代码介绍。
  • java类中代码执行顺序

    万次阅读 2018-08-20 15:58:52
    java类中代码执行顺序  首先,没有学java或者不知道类继承的,可以不用浪费时间乐,直接左上角,看多了有害。  java的代码执行顺序是自上而下,从左到右,方法是以main方法为主方法(通常情况下,事实上很...
  • Java中Static执行顺序

    千次阅读 2018-08-11 16:09:15
    也就是说说被static关键字修饰的方法或者变量**不需要依赖于对象来进行访问**,只要被加载了,就可以通过类名去进行访问 static代码块  static关键字还有一个比较关键的作用就是用来形...
  • B继承类A,当实例化一个B类型时,执行顺序为: A的静态代码块->B的静态代码块->A的构造代码块->A的无参构造函数->B的构造代码块->B的无参构造函数public class Test1 { ...
  • 随笔 - 150 文章 - 0 评论 - 465java中带继承类的加载顺序详解及实战一、背景: 在面试中,在java基础方面,的加载顺序经常被问及,很多时候我们是搞不清楚到底的加载顺序是怎么样的,那么今天我们就来看看带...
  • java继承构造方法调用顺序

    千次阅读 2021-11-26 19:28:45
    首先根据带参数的对象去找相应的构造方法,在Child中找到了带参数的构造方法, 2.因为有super(name)的语句存在,所以会去调用父类的带参数的构造方法,输出People(String name); 3、回到子类中执行输出Child...
  • java 子类继承父类各方法的执行顺序

    千次阅读 2018-05-01 18:24:03
    结论: java中子类继承父类各方法的执行顺序:(这里只写jvm自动调用的方法的顺序,包括静态代码块、代码块、构造方法) 1、第一次创建子类对象 父类静态代码块 子类静态代码块 父类代码块 父类构造方法 子类...
  • Java的实例化顺序(程序执行顺序

    千次阅读 多人点赞 2018-09-12 15:19:04
    加载/执行顺序: 牢记一点: 静态和非静态分开处理 使用到静态加载时,静态又分为: 静态变量, 静态代码块, 其中加载顺序是按照中书写的先后顺序加载的 非静态加载顺序: 按照非静态书写顺序加载/执行 静态...
  • 【深入理解JVM】:Java类继承关系中的初始化顺序

    万次阅读 多人点赞 2016-05-06 11:19:38
    Java类初始化的顺序经常让人犯迷糊,现在本文尝试着从JVM的角度,对Java继承继承关系中的初始化顺序进行试验,尝试给出JVM角度的解释。非继承关系中的初始化顺序对于非继承关系,主类...
  • Java笔记——Java代码块的执行顺序

    千次阅读 2018-09-07 02:12:06
    Java代码块的执行顺序 Java程序中代码块的执行顺序对于学习Java的人来说是必不可少需要掌握的。 代码块 在Java中,使用{}括起来的代码被称为代码块。 根据其位置和声明的不同,可以分为: 局部代码块 构造...
  • java 执行顺序, 创建一个对象时,先执行该中的static,然后执行继承的父类的构造,然后执行匿名,最后执行自己的构造 也就是说,在我们的程序中,实例化一个对象的时候,运行顺序为: 1. 父类静态块 2. ...
  • Java类初始化顺序

    2020-12-22 23:54:19
    所有构造方法执行顺序如下: 执行父类的构造方法。没有继承默认继承的Object。Object会开辟一块内存,初始化所有数据为0、null、false等默认值 执行本中的成员代码块。所有代码块是从上往下顺序执行的,所以代码...
  • java 子类继承父类 加载顺序

    千次阅读 2018-03-19 23:00:17
    父类如下 ... import org.springframework.stereotype.Service; @Service public class TestService { ...第二局话,因为当加载的时候先加载静态相关,随后是普通成员变量 所以继承加载顺序加上子类加上顺序就出来了
  • java类中方法的执行顺序

    千次阅读 2016-10-04 12:23:28
    静态平级---->new的先执行代码块 再执行构造器,按照顺序执行 static{}代码块--->如果是static Test t1=new Test() 因为获得了new对象,先执行普通代码块(按照代码顺序),在执行构造器---> 如果是static int x=...
  •  由于这边不是java的运行环境不能使用debug查看具体的执行顺序,所以在以下演示代码中,将使用红色序号标志重要的行,在分析中会更容易理解、明了。 演示代码如下:此代码的输出值为:0 package util;
  • Java中,子类实例化时会调用父类构造方法,子类父类方法中会有一个函数生成表,执行时实现动态链接,子类重写父类方法时执行顺序也是这样  对于执行父类构造方法的问题。可以归纳为两种情况 1,如果...
  • Java类的初始化顺序 Java 父类构造函数,父类静态成员变量,父类普通成员变量,父类静态代码块,父类代码块, 子类构造函数 子类静态成员变量,子类普通成员变量,子类静态代码块,子类代码块执行顺序 没有继承...
  • Java面试中经常遇到的类执行顺序

    千次阅读 2017-04-18 20:06:12
    类执行顺序: 下面是我写的一个demo: package com.bw; /** * @author brickworker * 关于Color的描述:测试单个执行顺序问题 */ public class Color {  //构造函数  public Color() {  System.out....
  • java继承中new子类对象的执行顺序

    千次阅读 2017-05-13 19:55:10
    下面测试代码块,静态代码块,构造器的初始化顺序 public class TestExtends { public static void main(String[] args) { A a = new A(5); /*输出结果: * B constructor A.draw(), radius = 0 A constructor A....
  • java继承时候执行顺序问题

    千次阅读 2014-04-22 20:51:49
    当子类继承父类之后,创建子类对象时,会先调用父类的构造函数,然后再调用子类构造函数。
  • java类执行顺序

    千次阅读 2018-01-17 17:44:34
    1.首先我们先创建一个java类 (随便建的,命名不规范,请忽视) public class java extends javaFather{ private int id; private String name; static { System.out.println("我是静态方法"); } { System
  • Java的加载顺序介绍(ClassLoader)

    万次阅读 多人点赞 2018-06-02 10:05:37
    Java的加载顺序介绍(ClassLoader)1、ClassNotFoundExcetpion 我们在开发中,经常可以遇见java.lang.ClassNotFoundExcetpion这个异常,今天我就来总结一下这个问题。对于这个异常,它实质涉及到了java技术体系中...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 244,645
精华内容 97,858
关键字:

java继承类的执行顺序

java 订阅