1、构造函数是用来干什么的

构造函数是用来初始化对象的成员属性的。

举个例子:

public class MyClass {private String name;private int id;public MyClass(String name, int id){this.name = name;this.id = id;}
}

在main方法里new一个MyClass对象的过程如下:

public class Main {public static void main(String[] args) {String name = "Jerry";int id = 1;MyClass myClass = new MyClass(name, id);}
}

  1. 通过new关键字创建一个MyClass对象,并在堆区为这个新创建的对象分配内存空间;
  2. 调用MyClass类的构造函数为这个新创建的对象初始化其成员属性name和id;
  3. 声明一个指向MyClass类型的对象引用myClass,令其指向1中新创建的对象(即myClass变量的值为1中新创建对象的内存地址)。

注意一个对象建立的过程中,构造函数仅执行一次,后面想对对象的成员做改变等操作可以调用getter/setter方法。

2、构造函数特点

构造函数也是类里的一个函数,跟普通函数不同,构造函数主要有以下几个特点:

  • 构造函数的名称必须与类名相同,区分大小写;
  • 构造函数没有返回值,也不能用void修饰;
  • 构造函数可以用任何访问修饰符(public、protected和private)修饰;
  • 构造函数不能用static、final、abstract和synchronized等关键字修饰;
  • 构造函数不能被覆写(override);
  • 构造函数可以被重载(overload),以参数的个数、类型及顺序区分;
  • 重载意味着一个类里可以有多个构造函数,构造函数1可以调用构造函数2完成对象初始化,通过this关键字:this(参数1,参数2...)实现;
  • 接口里没有构造函数,抽象类里可以有构造函数,也可以没有,抽象类的构造函数在创建继承自抽象类的子类的对象时会被调用;

3、构造函数分类

构造函数分为有参构造函数、无参构造函数和默认构造函数。

3.1 有参构造函数

带入参的构造函数叫有参构造函数,上面例子里就是有参构造函数。

3.2 无参构造函数

不带入参的构造函数叫无参构造函数。无参构造函数对类的成员初始化有下面两种方法:

(1)在类成员变量声明时进行初始化

public class MyClass {private String name = "Jerry";private int id = 1;public MyClass(){}
}

(2)在无参构造函数的方法体里对类成员变量初始化

public class MyClass {private String name;private int id;public MyClass(){this.name = "Jerry";this.id = 1;}
}

3.3 默认构造函数

当类里没有显式地定义代码来实现任何构造函数时,Java编译器将会在编译的字节码(.class文件)里面为这个类插入默认构造函数。由于是在编译阶段插入,因此在源文件(.java)里是不会找到默认构造函数的代码的。

默认构造函数形式上类似无参构造函数(都没有入参),但是二者并不能划等号,区别如下:

  • 默认构造函数方法体为空,无参构造函数方法体可以为空也可以不为空;
  • 只要类里显式的创建了一个构造函数,比如一个无参构造函数,编译器都不会再为这个类创建默认构造函数了。

4、子类中调用父类的构造函数

在Java中,子类的构造函数必须调用父类的构造函数,这个调用可以是隐式地调用,即代码里没有直接调用父类构造函数,但是编译器会默认调用父类的无参构造函数或者默认构造函数;也可以显示地通过super关键字调用父类的构造函数,总之一句话:子类的构造函数必须调用父类的构造函数。

子类中调用父类的构造函数分为以下两个场景:

  • 当父类定义了无参构造函数,或者父类源码里没有显式定义构造函数而是编译器插入了一个默认构造函数,则子类构造函数里可以不显式地调用父类构造函数,此时编译器会在子类的构造函数里默认调用父类的无参构造函数或者默认构造函数;
  • 当父类没有定义无参构造函数,且定义了有参构造函数,则在子类的构造函数里必须通过super语句显式地调用父类的有参构造函数。

(1)对于第一个场景,且父类里包含无参构造函数,举例如下:

父类:

public class Dog {private String name;public Dog(){System.out.println("调用Dog类的无参构造函数");}
}

子类:

public class YellowDog extends Dog {private String name;public YellowDog(){System.out.println("调用YellowDog类的无参构造函数");}
}

main函数:

public class Main {public static void main(String[] args) {Dog dog = new YellowDog();}
}

结果如下:

调用Dog类的无参构造函数
调用YellowDog类的无参构造函数

此时创建子类对象时,会先调用父类的无参构造函数,再调用子类的无参构造函数。

如果把父类的无参构造函数去掉,即父类里不定义任何构造函数,此时运行结果如下:

调用YellowDog类的无参构造函数

此时创建子类对象时,会先调用父类的默认构造函数,再调用子类的无参构造函数。

(2)对于第二个场景,举例如下:

父类:

public class Dog {private String name;public Dog(String name){this.name= name;System.out.println("调用Dog类的有参构造函数");}
}

父类里不包含无参构造函数,仅有有参构造函数,此时子类如果不显式地调用父类的有参构造函数会报错,如图:

提示父类里没有默认构造函数,那是因为子类里没有显式地调用父类构造函数,编译器会去父类里寻找无参构造函数,无参构造函数也没有就看能否找到默认构造函数,默认构造函数也找不到就会报上面的错误。

正确的做法是在子类里通过super语句显式地调用父类的构造函数,如下:

子类:

public class YellowDog extends Dog {private String name;public YellowDog(String name){super(name);System.out.println("调用YellowDog类的有参构造函数");}
}

Main函数:

public class Main {public static void main(String[] args) {String name = "Jerry";Dog dog = new YellowDog(name);}
}

执行main函数结果如下:

调用Dog类的有参构造函数
调用YellowDog类的有参构造函数

此时创建子类对象时,会先调用父类的有参构造函数,再调用子类的有参构造函数。

参考

lea:Java中的构造函数——通过示例学习Java编程(14)​zhuanlan.zhihu.com

https://blog.csdn.net/yuyan1988nb/article/details/78133738​blog.csdn.netJava里的构造函数(构造方法) - LivterJA - 博客园​www.cnblogs.com

5、this调用语句必须是构造函数中的第一个可执行语句_Java 构造函数相关推荐

  1. 5、this调用语句必须是构造函数中的第一个可执行语句_ES6中的Promise和Generator详解...

    简介 ES6中除了上篇文章讲过的语法新特性和一些新的API之外,还有两个非常重要的新特性就是Promise和Generator,今天我们将会详细讲解一下这两个新特性. Promise 什么是Promi ...

  2. this调用语句必须是构造函数中的第一个可执行语句_详解-JavaScript 的 this 指向和绑定...

    JavaScript 中的 new.bind.call.apply 实际这些都离不开 this,因此本文将着重讨论 this,在此过程中分别讲解其他相关知识点. 注意: 本文属于基础篇,请大神绕路.如 ...

  3. this调用语句必须是构造函数中的第一个可执行语句_谈谈JavaScript中的函数构造式和new关键字...

    您是否曾困惑于 Javascript 中的new关键字呢?是否曾想理解关于 function 和 constructor 的区别是什么呢? 大多数 Javascript 的新开发者不太想要使用new关 ...

  4. java结束程序是什么语句,在Java程序中,每条功能执行语句的最后都必须用结束。...

    在Java程序中,每条功能执行语句的最后都必须用结束. 答: 分号 热继电器可以实现短路保护和过载保护 答:× 皮亚杰用表示通过作用或者操控物体和事件来发现其特点从而获取知识的人 答:建构者 品行包括 ...

  5. 为什么this()和super()必须是构造函数中的第一条语句?

    Java要求,如果您在构造函数中调用this()或super(),则它必须是第一条语句. 为什么? 例如: public class MyClass {public MyClass(int x) {} ...

  6. [转载] 为什么this()和super()必须是构造函数中的第一条语句?

    参考链接: Java中的构造函数链接(带示例) Java要求,如果您在构造函数中调用this()或super(),则它必须是第一条语句. 为什么? 例如: public class MyClass { ...

  7. java super构造函数_Java为什么this()和super()必须是构造函数中的第一条语句?...

    Java要求,如果你在构造函数中调用this()或super(),则它必须是第一条语句.为什么? 例如: public class MyClass { public MyClass(int x) {} ...

  8. sql语句截断_SQL Server中SQL截断和SQL删除语句之间的区别

    sql语句截断 We get the requirement to remove the data from the relational SQL table. We can use both SQL ...

  9. 程序实现switch语句判断年龄_【回顾】(选择执行语句if else和switch)乐创DIY C语言讲义——3.8节(4)...

    文    |    Edward 4 选择执行语句有些时候,我们希望程序既不顺序执行,也不只做单一的判断(代码运行还是不运行),很多时候,我们往往只希望对某一个条件的不同状态分别执行不同的语句,这样就 ...

最新文章

  1. catia直线测距怎么调出来_为户外远程测距而生
  2. nginx DNS 缓存问题
  3. J - 数据结构实验:哈希表
  4. 再谈STM32的CAN过滤器-bxCAN的过滤器的4种工作模式以及使用方法总结
  5. 关于ST02看到SWAP红色的讨论
  6. GDCM:gdcm::Anonymizer的测试程序
  7. 汇编语言(十八)之求两个数的最大公约数
  8. 从蚂蚁金服实践入手,带你深入了解 Service Mesh
  9. 云数据库·ApsaraDB 产品6月刊
  10. 主备库内存不一致的Data Guard环境搭建全过程
  11. python模型训练框架_以Python撰写 AI模型框架
  12. Redis:从应用到底层,都在这儿了!
  13. 程序员面试宝典 笔记 第七章
  14. 德标螺纹规格对照表_英制螺纹对照表详细介绍,英制螺丝螺纹标准
  15. 基于OpenPose的人体姿态检测
  16. RGB颜色查询对照表
  17. 线程的终止的4种方式
  18. 防火墙之ipsec vpn实验
  19. 2023北京理工大学计算机考研信息汇总
  20. Revit模型在Web端展示的免费方案

热门文章

  1. python中常见的异常
  2. ResNext(2017)解读
  3. 【2020蓝桥杯】Python组真题解析 - 第十一届蓝桥杯
  4. linux配置桌面快捷方式:idea.desktop快捷方式文件编写
  5. Java客户端操作HBase:创建表代码示例
  6. kafka生产者、消费者消息操作命令
  7. 2021年office2010每次打开都要配置进度解决方法
  8. 【收藏】Hadoop解决Could not locate executable null\bin\winutils.exe in the Hadoop binaries.问题
  9. K8S报错:controller-manager Unhealthy Get http://127.0.0.1:10252/healthz: dial tcp 127.0.0.1:10252
  10. ubuntu16.04将普通用户提升至root权限