精华内容
下载资源
问答
  • java 子类和父类构造函数关系

    在创建子类的对象时,jvm会首先执行父类的构造方法,然后再执行子类的构造方法,如果是多级继承,会先执行最顶级父类的构造方法,然后依次执行各级个子类的构造方法

    package com.my.test;
    public class Son extends  Father{
    	SonProp r=new SonProp();
    	public Son()
    	{
    		System.out.println(" Son is construct");		
    	}
    	public static void main(String[] args)
    	{		
    		new Son();
    	}	
    }
    class SonProp
    {
    	public SonProp()
    	{
    		System.out.println(" SonProp is construct");		
    	}
    }
    class FatherProp
    {
    	public FatherProp()
    	{
    		System.out.println(" FatherProp is construct");		
    	}
    	
    }
    class Father
    {
    	FatherProp sonProp=new FatherProp();
    	public Father()
    	{
    		System.out.println(" Father is construct");		
    	}	
    }
    
    执行结果为:
    
     FatherProp is construct
     Father is construct
     SonProp is construct
     Son is construct


    java继承中对构造函数是不继承的。
    
    以下是例子:
    
     public class FatherClass {
     public FatherClass() {
           System.out.println(100);
     }
    
     public FatherClass(int age) {
          System.out.println(age);
     }
    
    }
    
     
    
    public class SonClass extends FatherClass{
    
            public SonClass() {
             }
            public SonClass(int c) {
                     System.out.println(1234);
            }
       
     public static void main(String[] args) {
    
      FatherClass f = new FatherClass(28);
      SonClass s = new SonClass(66);
     
     }
    }
    
    编译后执行结果如下是什么呢?
    
    分析:1. FatherClass f = new FatherClass(28);这句没有必要解释
    
    2.SonClass s = new SonClass(66);执行这句时,调用
    
     public SonClass(int c) {
                     System.out.println(1234);
            }
    
    
    在这个构造函数中,等价于
    
     public SonClass(int c) {
    
                    super();//必须是第1行,否则不能编译
                     System.out.println(1234);
            }
    
    所以结果是    100
                             1234
    
    3.如果子类构造函数是这样写的
    
    public SonClass(int c) {
    
                    super(22);//必须是第1行,否则不能编译
    
                   //显示调用了super后,系统就不再调用super();
                     System.out.println(1234);
            }
    
    执行结果是   22
                             1234
    
    总结1:构造函数不能继承,只是调用而已。
    
    如果父类没有无参构造函数
    
    创建子类时,不能编译,除非在构造函数代码体中第一行,必须是第一行显示调用父类有参构造函数
    
    如下:
    
    SonClass (){
    
    super(777);//显示调用父类有参构造函数
    
    System.out.println(66);
    
    }
    
    如果不显示调用父类有参构造函数,系统会默认调用父类无参构造函数super();
    
    但是父类中没有无参构造函数,那它不是不能调用了。所以编译就无法通过了。
    
    总结2:创建有参构造函数后,系统就不再有默认无参构造函数。
    
    如果没有任何构造函数,系统会默认有一个无参构造函数。

    展开全文
  • Java子类和父类的初始化执行顺序

    千次阅读 多人点赞 2019-12-22 00:01:42
    有个朋友在CSDN评论区问我,java子类和父类初始化时各个代码块的执行顺序,我本来写好了一大段回复,点击发表回复,结果没有回复成功,我写的评论也不见了。。。csdn的评论区编辑体验本来就不好,然后还有这种回复...

    有个朋友在CSDN评论区问我,java子类和父类初始化时各个代码块的执行顺序,我本来写好了一大段回复,点击发表回复,结果没有回复成功,我写的评论也不见了。。。csdn的评论区编辑体验本来就不好,然后还有这种回复失败的问题,这体验真是一言难尽,干脆再写一篇文章,从字节码层面来看这个顺序问题,希望可以帮到更多朋友。


    吐槽完毕,回归正题。

    要明白子类和父类的初始化执行顺序,只需要知晓以下三点,就不会再弄错了。

    1.创建子类对象时,子类和父类的静态块和构造方法的执行顺序为:父类静态块->子类静态块->父类构造器->子类构造器。深入理解为什么是这个顺序,可以看我这篇文章:从京东面试题看java类和对象的初始化

     

    2.静态变量的声明和赋值,声明会在静态块之前,赋值运算将会合并到静态块中,顺序和源代码中的顺序一致。举例如下:

    源代码

    public class P {
    
        public static int a = 1;
    
        static {
            int b = 2;
        }
    
        public static int c = 3;
    }

    在编译器编译后,会变成这样子

    public class P {
    
        public static int a;
        public static int c;
    
        static {
            a = 1;
            int b = 2;
            c = 3;
        }
    
    }

    我们来看,编译后的字节码是怎样的,使用命令可以反编译类的字节码:javap -v -p P.class 

    {
      public static int a;
        descriptor: I
        flags: ACC_PUBLIC, ACC_STATIC
    
      public static int c;
        descriptor: I
        flags: ACC_PUBLIC, ACC_STATIC
    
      static {};
        descriptor: ()V
        flags: ACC_STATIC
        Code:
          stack=1, locals=1, args_size=0
             0: iconst_1
             1: putstatic     #2                  // Field a:I
             4: iconst_2
             5: istore_0
             6: iconst_3
             7: putstatic     #3                  // Field c:I
            10: return
    }

    我去掉了编译器生成的构造方法以及一些无关信息,我们可以看到字节码中,a、c的声明在前面(其实这个不是重点),在static{}块中,pc 0~1两个指令,为静态字段a赋值1,pc 4~5两个指令,为第一个局部变量,也就是变量b赋值2,pc 6~7两个指令,为静态字段c赋值3。可以看到合并后的static块,a的赋值在原静态块代码之前,c的赋值在原静态块代码之后,这个顺序和源代码中ac的声明顺序一致。

     

    3.成员变量的声明和赋值,与静态变量相同的是成员变量的赋值也会合并到构造器中,不同的是合并后的顺序,成员变量的赋值是在构造器的前面。举例如下:

    源代码

    public class P {
    
        public int a = 1;
    
        public P() {
            int b = 2;
        }
    
        public int c = 3;
    
    }

    编译后的代码,会像这个样子

    public class P {
    
        public int a;
        public int c;
    
        public P() {
            a = 1;
            c = 3;
            int b = 2;
        }
    }

    再来看看编译后的字节码是怎样的

      public int a;
        descriptor: I
        flags: ACC_PUBLIC
    
      public int c;
        descriptor: I
        flags: ACC_PUBLIC
    
      public P();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=2, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: aload_0
             5: iconst_1
             6: putfield      #2                  // Field a:I
             9: aload_0
            10: iconst_3
            11: putfield      #3                  // Field c:I
            14: iconst_2
            15: istore_1
            16: return

    字段a和c的声明在前面,然后看构造器P()的字节码,pc 0~1两个指令,是先调用P的父类Object的构造器,字节码中的构造器方法使用<init>来表示的。pc 4~6三个指令,为成员变量a赋值1。pc9~11三个指令,为成员变量c赋值3,pc 14~15两个指令,为下表为1的局部变量赋值为2,也就是局部变量b=2。所以可以看出,成员变量赋值逻辑合并到构造器后,是在调用父类构造器之后,原有构造器代码之前。


    回过头来,你明白了子类父类初始化各个方法的执行顺序,而字段的初始化赋值也是合并到方法里,所以创建子类对象时,子类父类各个部分的执行顺序都已了然。

    总结:

    1.讲解了子类父类初始化时方法执行顺序,包括的静态块和构造器方法,静态块也是方法,静态块在jvm中的方法名叫<cinit>。

    2.讲解了字段的赋值是如何合并到方法中,静态字段赋值合并到静态块中,成员变量赋值合并到构造器方法中。

     

     

     

    展开全文
  • JAVA中,子类通过extends继承父类创建子类对象时,会自动调用所有父类构造方法(从最原始父类逐层调用)。 方法是通过super()(系统默认,不需要显式申明)方法调用,注意这里的super函数可以传递对象参数。 ...

    JAVA中,子类通过extends继承父类,创建子类对象时,会自动调用所有父类构造方法(从最原始父类逐层调用)。
    方法是通过super()(系统默认,不需要显式申明)方法调用,注意这里的super函数可以传递对象参数。

    展开全文
  • java 子类继承父类运行顺序

    千次阅读 2016-08-24 17:29:10
    java 子类继承父类运行顺序

    平时项目经常用到 子类继承父类 但对执行顺序一直不太清楚,花时间捋一捋,重新学习一下,感觉有些收获

    现在我们有两个类 

    public class TestSta1 {
    	
    	static {
    		System.out.println("this static TestSta1    	<span style="white-space:pre">	</span>1");
    	}
    	
    	{
    		System.out.println("this TestSta1		<span style="white-space:pre">	</span>3");
    	}
    	
    	public TestSta1(){
    		System.out.println("this TestSta1(str)		<span style="white-space:pre">	</span>4");
    	}
    	
    }


    public class TestSta2 extends TestSta1{
    	
    	public TestSta2() {
    		System.out.println("this TestSta2()       		7");
    	}
    	
    	static{
    		System.out.println("this static testSta2    	<span style="white-space:pre">	</span>2");
    	}
    	
    	{
    		System.out.println("this teststa2		5");
    	}
    	
    	{
    		System.out.println("this teststa2		6");
    	}
    	
    	public static void main(String[] args) {
    		new TestSta2();
    	}
    	
    }
    执行结果  

    this static TestSta1    	1
    this static testSta2    	2
    this TestSta1			3
    this TestSta1(str)		4
    this teststa2		<span style="white-space:pre">	</span>5
    this teststa2		<span style="white-space:pre">	</span>6
    this TestSta2()       		7
    我们都知道,java的机制是先编译成字节码文件.class  然后在JVM上解释器逐行翻译成机器码文件,那从.class 到JVM加载的时候,就执行static代码块和static变量,所以先执行静态代码块,并且执行顺序是先执行父类的在执行子类的,当执行开始执行到 new TestSta2(); 

    创建对象的时候,调用了它的无参构造,所有子类的构造方法第一行的时候都隐含 super()

    public TestSta2() {
    	super();
    	// TODO Auto-generated constructor stub
    }
    所以会调用父类的构造方法,而每次在执行构造方法之前都会执行代码块,父类的代码块,父类的构造方法执行完毕之后,开始执行子类的代码块,构造方法,

    如果我们修改一些东西

    public static void main(String[] args) {
    	System.out.println(" main testSta1() ``````````````````");
    	new TestSta2();
    }
    会发现执行顺序

    this static TestSta1    	1
    this static testSta2    	2
     main testSta1() ``````````````````
    this TestSta1			3
    this TestSta1(str)		4
    this teststa2		<span style="white-space:pre">	</span>5
    this teststa2		<span style="white-space:pre">	</span>6
    this TestSta2()       		7
    静态代码块执行顺序在main方法之前

    如果我们重新建个类

    public class TestSta3 {
    	public static void main(String[] args) {
    		System.out.println("  main teststa3 ~~~~~~~~~~~~~~");
    		new TestSta2();
    	}
    }
    执行顺序

      main teststa3 ~~~~~~~~~~~~~~
    this static TestSta1    	1
    this static testSta2    	2
    this TestSta1			3
    this TestSta1(str)		4
    this teststa2		<span style="white-space:pre">	</span>5
    this teststa2		<span style="white-space:pre">	</span>6
    this TestSta2()       		7
    我的理解我们在TestSta2 起main 方法的时候,JVM会首先加载TestSta2.class的时候开始初始化静态代码块,而如果在TestSta3 起main方法,JVM会首先加载TestSta3,只有执行到 new TestSta2(); 时 会加载TestSta2.class  才会初始化静态代码块

    最后总结一下执行顺序

    1.父类静态代码块

    2.子类静态代码块

    3.父类代码块

    4.父类构造

    5.子类代码块

    6.子类构造


    展开全文
  • 实际过程是【先创建子类对象,创建过程进行一半,再去创建父类对象,父类对象创建完毕,再接着创建子类对象。】这种递归的流程。 =========以下 了解。勿纠结============= 涉及到一道经典面试题:。。。。 ...
  • Java子类继承父类构造器

    千次阅读 2018-05-04 11:16:26
    一、研究问题1....二、创建父类创建父类Animal,有两个构造器class Animal{ private Integer high; public Animal() { System.out.println("Animal()"); } public Animal(Integer high)...
  • 导读Java语言中,在子类中定义与父类同返同名同参的方法将会出现“重写(覆写)”,子类将屏蔽父类的.../*需求:设计一个简单的java程序,证明子类重写父类方法的过程思路: 1、创建父类对象,通过父类对象调用该方法...
  • 本文主要介绍Java里常用的子类和父类的变量实例化顺序及陷阱,并结合一个Android实例来探讨此问题。日后编程中应尽量避免此陷阱。首先看下面一段代码:定义一个虚类Server.javapackage org.yanzi.test1; public ...
  • java中一个类首先是被加载到内存后,再去按顺序执行类中的static完成初始化,在加载过程先是加载父类,在去加载子类。构建子类实例时,先创建父类的实例。执行构造方法时,先去初始化成员属性。举个例子说明下: ...
  • 在之前的博文JAVA中子类继承父类时构造方法的继承问题中,我们已经了解到了当子类对象实例化的时候,调用子类构造方法之前,会先调用父类的构造方法,在继承的机制中,创建一个子类对象,同样会创建一个父类子对象,...
  • Java子类继承父类

    千次阅读 2015-08-07 15:57:30
    2.在子类中,可以使用父类中“public”“protected”定义的方法属性,也可以创建新的数据方法;没有访问“private”定义的方法属性的权限。 protected的使用方式: /** * Person.java */ package ...
  • 这里暂不考虑Java反射机制,于是我分析,子类不能继承父类私有的属性及方法,但是分析了内存后,我发现我是错的,在一个子类创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类...
  • Java子类调用父类构造方法

    万次阅读 多人点赞 2017-09-29 14:49:15
    Java中,子类的构造过程中,必须调用其父类的构造函数,是因为有继承关系存在时,子类要把父类的内容继承下来,通过什么手段做到的?   答案如下:   当你new一个子类对象的时候,必须首先要new一个父类...
  • (2)如果父类显式的添加无参构造函数,则子类可以创建自己的有参或无参构造函数,如果子类没有显示调用父类的有参构造函数,则java自动调用父类的无参构造函数。 (3)如果父类没有显式的添加无参构造函...
  • Java 子类继承父类方法

    千次阅读 2019-05-22 09:13:32
    类 A 称为基类(父类),类 B 称为派生类(子类) 类继承关系语法形式 Class 派生类名:基本名表 { 数据成员函数声明 } 基本名表 构成 访问控制 基类名1, 访问控制 基本名2,……..,问控制 基本名...
  • java子类父类继承

    2019-11-07 08:35:39
    继承:子类调用super()无参构造器;举个例子: 最好理解执行内存图; 1、.java文件编译完之后 在内存中后会个代码区存放; 2、主函数 main放里面的代码按顺序执行,main()进栈 ...不会再创建一个父类对象 ...
  • Java子类父类之间的对象转换(说明继承)

    万次阅读 多人点赞 2018-04-24 22:57:12
    在使用Java的多态机制时,常常使用的一个特性便是子类和父类之间的对象转换。从子类父类的转换称为向上转换(upcasting),通过向上转换,我们能够在编写程序时采用通用程序设计的思想,在需要使用子类对象的时候...
  • 今天突然想起以前做的一个试题,有关子类和父类静态代码块中执行顺序的问题,在代码中子类父类的静态代码块是怎么执行的,有覆盖吗,是继承的还是怎么样的?对此做了一个小的测试: 一个People父类: public ...
  • Java 子类继承父类调用顺序

    千次阅读 2019-01-18 12:37:55
    父类静态代码块(注意静态代码块只有首次创建才会执行,之后创建均不执行) 子类静态代码块 父类非静态代码块 父类构造方法 子类非静态代码块 子类构造方法 多态 this.method(o) &amp;amp;amp;gt; super....
  • java 子类继承父类各方法的执行顺序

    千次阅读 2018-05-01 18:24:03
    结论: java中子类继承父类各方法的执行顺序:(这里只写jvm自动调用的方法的顺序,包括静态代码块、代码块、构造方法) 1、第一次创建子类对象 父类静态代码块 子类静态代码块 父类代码块 父类构造方法 子类...
  • java中,父类子类、静态成员等各种初始化顺序很令人头痛,简单从下面的例子说起吧。 package study; public class Static{ static{ System.out.printIn("the first static block"); } public Static(){ ...
  • java中,子类继承父类时,子类必须调用父类的构造方法,如果类没有构造方法,会自动声明无参构造方法,反之,则不会创建子类的构造方法默认会调用父类的无参构造方法,如果父类没有无参构造方法,子类必须显示...
  • 【修饰符】class 子类名 extends 父类名 { 属性成员的定义; 方法成员的定义; } 【修饰符】:用来说明类的访问权限(public ,absttrct等) 只能继承一个父类 public class Son extends Father { } 调用父类的无...
  • 创建子类对象时,Student s = new Student("school"); 该构造方法中没有显示调用父类的 构造方法,但还是编译成功了,![图片说明](https://img-ask.csdn.net/upload/201604/14/1460599555_25628.png) 该构造方法...
  • Java中,子类实例化时会调用父类构造方法,子类父类方法中会有一个函数生成表,执行时实现动态链接,子类重写父类方法时执行顺序也是这样  对于执行父类构造方法的问题。可以归纳为两种情况 1,如果...
  • Java子类访问父类私有变量的思考

    千次阅读 2020-06-30 17:42:12
    父类User,包含私有变量namemoney; 以及两个构造函数基本的getter方法。 public class User { public User() { } public User(String name, int money) { this.name = name; this.money = money; } ...
  • Java子类父类是否继承private?

    千次阅读 2019-03-06 13:35:36
    1.java中子类中是否有父类的私有成员属性? 需要明确,父类的私有成员是不能被子类继承的么为何在这里输出的是父类的值?...(2)还是说创建子类对象时同时 class Father { private int a = 1; private in...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 233,581
精华内容 93,432
关键字:

java子类和父类的创建

java 订阅