图解 & 深入浅出Java初始化与清理:构造器必知必会
Writer :BYSocket(泥沙砖瓦浆木匠)
微 博:BYSocket
豆 瓣:BYSocket
FaceBook:BYSocket
Twitter :BYSocket
在面向对象编程中,编程人员应该在意“资源”。比如
|
1
|
<font color="#000000">String hello = "hello"; </font> |
在代码中,我们很在意在内存中String类型的hello,它是有一个生命周期的。在它生命周期中,初始化(initialization)和清理(cleanup)是两个重要的环节。尤其是C程序中,很多bug会出现在对象初始化和清理的环节。这样会造成一些程序安全问题。
《Think in Java》中说道:
随着计算机革命的发展,”不安全“的编程方式已逐渐成为编程代价高昂的主因之一。
一、栈与堆
在Java开发中,针对对象会在乎内存的两个区域:对象的生存空间是堆(heap) — 方法调用及局部变量(也称栈变量)的生存空间栈(stack)。如图:
![]()
二、什么是构造器,默认(无参)构造器
为了保证对象成功初始化,Java像C++一样引入了构造器(Constructor),即在创建对象的时候被自动调用的特殊方法。自然,Java额外提供了GC(垃圾回收器),对于不再使用的资源,垃圾回收机制会自动释放资源。Java通过类构造器创建新对象的时候,在使用此对象前,会调用其构造器进行初始化。如:
|
1
2
3
4
5
6
7
8
9
10
|
<font color="#000000">public class VoidConstructor { VoidConstructor(){ // 构造器 } void VoidConstructor() { // void 方法,不是构造器 }}</font> |
1、默认构造器
这里,VoidConstructor是一个类,如果需要创建一个VoidConstructor对象只要
|
1
|
<font color="#000000">VoidConstructor constr = new VoidConstructor();</font> |
调用上面的代码就可以通过这个默认构造器(即无参构造器),就生成一个VoidConstuctor对象。代码图解如下
![]()
2、注意,构造器是特殊的方法,采取与类名同名。它没有返回值,这与返回值为空的void方法不同。这里,void方法名命名也是不规范,应该是“每个方法首字母小写”,也一般不与类名相同。
另外,就算你类没有写构造器的话,编译器会生成一个默认构造器。
三、带参构造器
下面跑个带参构造器的例子:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/** * @author Jeff Lee * @since 2015-9-7 16:54:19 * 带参数简单构造器的展示 */public class SimpleConstructor2 { public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Child2(i); } }}// Child类class Child2 { Child2(int i) {// 带参数的Child类构造器 System.out.print("Child init " + i + " "); }} |
Eclipse中,右键Run as — java application:
![]()
上面Child2(int)是Child类的唯一构造器,此时你先在编译器中通过 new Child2()来创建对象是不行的。
所以,构造器有助于避免开发中出现代码错误。
二者,构造器可以用来初始化资源。其中,对象的创建与资源的初始化是捆绑在一起的。
休息一下吧~ 看看小广告:
开源代码都在我的gitHub上哦 — https://github.com/JeffLi1993 作者留言“请手贱,点项目star,支持支持拜托拜托”
四、继承中的构造器
在创建一个对象时,所以继承下来的对象都会被调用各构造器。比如说下面这个例子:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/** * @author Jeff Lee * @since 2015-9-10 08:56:18 * 继承中的构造器的案例 */public class ChildConstructor extends PersonConstructor{ ChildConstructor() {<br> //super();<br> System.out.println("Making a Child Modle..."); } @SuppressWarnings("unused") public static void main(String[] args) { ChildConstructor childConstructor = new ChildConstructor(); }}class PersonConstructor { PersonConstructor() { System.out.println("Making a Person Modle..."); }} |
main函数运行结果如下:
![]()
1. 先分析下类UML,ChildConstructor 继承 PersonConstructor,PersonConstructor 继承 Object:
![]()
2. super关键字,super用来调用父类的构造器。如果子类中没有super关键字,编译器会自动添加默认super()方法。因此,子类通过super()方法调用父类构造器。
3. 然后main函数中,通过new指令,启动了ChildConstructor对象的创建。子类 ChildConstructor 构造器在执行时,第一件事通过super()调用父类,这又会连锁反应到Objerct类。所以,打印控制台先输出 “父类先初始化”。
这过程就是构造器链(Constructor Chaining),即Child对象 is-a Person对象同时也 is-a Object对象。如果创建Child对象,也同时创建了Person对象和Object对象的部分。
4. 过程流程图详解(图中是各对象引用在堆栈块):
![]()
五、总结
构造器虽小,关键还是非常关键的。
本文小结:
1、默认构造器
2、有参构造器
3、继承中的构造器
还有第一点的知识基础补充
欢迎点击我的博客及GitHub — 博客提供RSS订阅哦!
———- http://www.bysocket.com/ ————- https://github.com/JeffLi1993 ———-
图解 & 深入浅出Java初始化与清理:构造器必知必会的更多相关文章
- 第4节:Java基础 - 必知必会(中)
第4节:Java基础 - 必知必会(中) 本小节是Java基础篇章的第二小节,主要讲述抽象类与接口的区别,注解以及反射等知识点. 一.抽象类和接口有什么区别 抽象类和接口的主要区别可以总结如下: 抽象 ...
- 必知必会之Java注解
必知必会之Java注解 目录 不定期更新中-- 元注解 @Documented @Indexed @Retention @Target 常用注解 @Deprecated @FunctionalInte ...
- Java面试必知必会(扩展)——Java基础
float f=3.4;是否正确? 不正确 3.4是双精度,将双精度赋值给浮点型属于向下转型,会造成精度损失: 因此需要强制类型转换: 方式一:float f=(float)3.4 方式二:float ...
- Java面试必知必会:基础
面试考察的知识点多而杂,要完全掌握需要花费大量的时间和精力.但是面试中经常被问到的知识点却没有多少,你完全可以用 20% 的时间去掌握 80% 常问的知识点. 一.基础 包括: 杂七杂八 面向对象 数 ...
- 第3节:Java基础 - 必知必会(上)
第3节:Java基础 - 必知必会(上) 本篇是基础篇的第一小节,我们从最基础的java知识点开始学习.本节涉及的知识点包括面向对象的三大特征:封装,继承和多态,并且对常见且容易混淆的重要概念覆盖和重 ...
- Java并发必知必会第三弹:用积木讲解ABA原理
Java并发必知必会第三弹:用积木讲解ABA原理 可落地的 Spring Cloud项目:PassJava 本篇主要内容如下 一.背景 上一节我们讲了程序员深夜惨遭老婆鄙视,原因竟是CAS原理太简单? ...
- 必知必会之 Java
必知必会之 Java 目录 不定期更新中-- 基础知识 数据计量单位 面向对象三大特性 基础数据类型 注释格式 访问修饰符 运算符 算数运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 三目表达式 ...
- 第5节:Java基础 - 必知必会(下)
第5节:Java基础 - 必知必会(下) 本小节是Java基础篇章的第三小节,主要讲述Java中的Exception与Error,JIT编译器以及值传递与引用传递的知识点. 一.Java中的Excep ...
- 脑残式网络编程入门(三):HTTP协议必知必会的一些知识
本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...
随机推荐
- ZooKeeper 3.5.0 分布式配置问题
ZooKeeper 3.5.0 分布式配置好后,执行./zkServer.sh start 命令启动,报如下错误: 2015-07-02 21:06:01,671 [myid:] - INFO [ma ...
- 2014-3-5 星期三 [New Change && New Start]
昨日进度: [计算方法]:起晚啦,迟到一点,有点困,可能因为睡得太晚吧! [无课]:制作IEEE标准在JAVA中的应用. [组成]:-- [多媒体]:-- [人工智能]:-- [寝室]:学习API. ...
- C#与数据库访问技术总结(九)之实例
实例 更新记录 在本例子中,建立一个供用户输入学生学号和姓名的文本框和几个对应不同操作类型的更新信息按钮,当用户输入信息以后单击相应的按钮则执行相应的操作.在此实例中还将接触到服务器信息验证的相关知识 ...
- JavaScript this 总结(含 ES6)
本文主要总结自<JavaScript 语言精粹>.部分总结自<JavaScript 高级程序设计>以及自己的经验 四种调用模式 在 JavaScript 中,this 的值取决 ...
- atitit.软件开发方法总结O6
atitit.软件开发方法总结O6 #--cmm/cmmi 都晓得这个. #--IPD集成产品开发 结构化的流程 IPD工具:包括业务及技术上的共工具. 5.考评:包括团队和个人绩效考核两个方面:首 ...
- Android 学习之显式激活与隐式激活Activity
在res界面里面有两个布局文件activity_main和acivity_two
- Spring之@Configuration配置解析
1.简单的示例: @Configuration @EnableConfigurationProperties({DemoProperties.class}) public class DemoConf ...
- MF-800U
MF-800U 价格:200元左右 https://item.taobao.com/item.htm?spm=a230r.1.14.6.kfkqoY&id=4963072384&ns= ...
- .net下BerkeleyDB操作封装C#版(附单元测试)
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System ...
- 使用eclipse JDT compile class,解决 无法确定 X 的类型参数;对于上限为 X,java.lang.Object 的类型变量 X,不存在唯一最大实例
ant 命令行方式执行build javac编译class出现 泛型无法转换 无法确定 <X>X 的类型参数:对于上限为 X,java.lang.Object 的类型变量 X,不存在唯一最 ...