图解 & 深入浅出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协议都是我们最常打交 ...
随机推荐
- Kali Linux Web 渗透测试— 第十二课-websploit
Kali Linux Web 渗透测试— 第十二课-websploit 文/玄魂 目录 Kali Linux Web 渗透测试— 第十二课-websploit..................... ...
- Qt之课外实践——文件操作(简单清道夫)
说明:这个小项目是关于文件操作的.主要的功能有:重复文件的查找(根据文件的大小),说白了,就是讲大小相同的文件在一起显示出来,供用户自由的选择删除.这个360云盘里的文件去重还差的很远.还有空文件夹的 ...
- intellij自动缩进排版
用鼠标选中需要缩进的代码块,然后输入命令 ctrl+alt+i ref: http://stackoverflow.com/questions/12264127/how-to-reindent-lin ...
- fgets函数执行完成后,文件指针如何移动?
用fgets执行之后,读取了文件中的一行,这时文件位置指针是自动指向文件的下一行的开头吗,还是指向当前行的结尾?如果一行的字符串没读取完会怎样? 实例结果: 如果一行的字符串没读取完会,下一次会接着上 ...
- 在sublime text 中的Emmet快捷键动态图演示
Emmet的前身是大名鼎鼎的Zen coding,如果你从事Web前端开发的话,对该插件一定不会陌生.它使用仿CSS选择器的语法来生成代码,大大提高了HTML/CSS代码编写的速度,比如下面的演示: ...
- (笔记)VC6插件安装(VC6LineNumberAddin)
VC6插件安装步骤如下: 1.下载VC6LineNumberAddin插件及注册文件.(以下是参考链接:) http://files.cnblogs.com/files/tdyizhen1314/VC ...
- ps、grep和kill联合使用杀掉进程
例如要杀掉hello这个进程,使用下面这个命令就能直接实现. ps -ef |grep hello |awk '{print $2}'|xargs kill -9 这里是输出ps -ef |gre ...
- python中x的平方
x ** 2 sqdEvens = [x ** 2 for x in range(8) if not x % 2] for i in sqdEvens: print(i) 0 4 16 36 > ...
- 在主方法中定义一个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。
//在主方法中定义一个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’:输出这个数组中的所有元素. char [][]y=new char [10][10 ...
- VC中打开对话框选择文件和文件夹
1.选择文件 CFileDialogdlg(true, NULL, NULL, NULL, "所有文件 | *.*", this); ...