图解 & 深入浅出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初始化与清理:构造器必知必会

时间: 2024-10-24 23:25:08

图解 & 深入浅出Java初始化与清理:构造器必知必会的相关文章

第4节:Java基础 - 必知必会(中)

第4节:Java基础 - 必知必会(中) 本小节是Java基础篇章的第二小节,主要讲述抽象类与接口的区别,注解以及反射等知识点. 一.抽象类和接口有什么区别 抽象类和接口的主要区别可以总结如下: 抽象类中可以没有抽象方法,JDK8版本开始提供了接口总方法的default实现 抽象类和类一样是单继承的:接口可以实现多个父类 抽象类中可以存在普通的成员变量:接口中的变量必须是static final类型的,必须被初始化,接口中只能有常量,没有变量 解析: 在Java中,我们用abstract来定义抽

一个老师程序员说:这是学Java 必知必会的 20 种常用类库和 API

一个有经验的Java开发人员特征之一就是善于使用已有的轮子来造车.<Effective Java>的作者Joshua Bloch曾经说过:"建议使用现有的API来开发,而不是重复造轮子".在本文中,我将分享一些Java开发人员应该熟悉的最有用的和必要的库和API.顺便说一句,这里不包括框架,如Spring和Hibernate因为他们非常有名,都有特定的功能.最后,如果大家如果在自学遇到困难,想找一个java的学习环境,可以加入我们的java学习圈,点击我加入吧,会节约很多时

第5节:Java基础 - 必知必会(下)

第5节:Java基础 - 必知必会(下) 本小节是Java基础篇章的第三小节,主要讲述Java中的Exception与Error,JIT编译器以及值传递与引用传递的知识点. 一.Java中的Exception和Error有什么区别 Exception和Error的主要区别可以概括如下: Exception是程序正常运行中预料到可能出现的错误,并且应该被捕获并进行相应处理,是一种异常现象. Error是正常情况下不可能发生的错误,Error会导致JVM处于已追踪不可恢复的状态,不需要捕获处理,比如

sql必知必会的数据初始化

之前已经配置好mysql的工作环境,但是还缺少可以进行操作的文件,即缺少对应的一个数据库和其中的5个表. 下载相关代码 在网址http://www.forta.com/books/0672325675/ 中下载相关文件,在这里我下载的是MySQL (and MariaDB) SQL scripts. 下载后进行解压,会有两个文件:create.txt和populate.txt. 数据库的建立 在mysql中输入:CREATE DATABASE OrderDb; 不要忘记分号,这是MySQL的语法

深入理解Kafka必知必会(2)

深入理解Kafka必知必会(1) Kafka目前有哪些内部topic,它们都有什么特征?各自的作用又是什么? __consumer_offsets:作用是保存 Kafka 消费者的位移信息 __transaction_state:用来存储事务日志消息 优先副本是什么?它有什么特殊的作用? 所谓的优先副本是指在AR集合列表中的第一个副本. 理想情况下,优先副本就是该分区的leader 副本,所以也可以称之为 preferred leader.Kafka 要确保所有主题的优先副本在 Kafka 集群

C++必知必会(4)

条款35 placement new 直接调用构造函数是行不通的,然而可以通过使用placement new来哄骗编译器调用构造函数: void *operatornew(size_t, void* p) throw() { return p;} placement new是operator new的一个标准的重载版本,也位于全局名字空间中,但和我们通常看到的operator new不同,语言明令禁止用户替换placement new,而普通的operator new和operator dele

《MySQL必知必会学习笔记》:正则表达式

正则表达式的应用 前面的几节的过滤例子允许用匹配.比较和通配操作符来寻找数据.对于基本的数据过滤,这样就足够了.但是随着过滤条件的复杂性的增加,where子句本身的复杂性也有必要增加.这也就是正则表达式变得有用的地方. 正则表达式是用来匹配文本中特殊的字符集合. 正则表达式不是自己第一次见,在JAVA/C++ 这些语言中,都有正则表达式,不过他们的用途是一样的,都是匹配文本中的字符串.可能具体的用法不太一样,但也差不多.下面将一一进行学习.介绍. 基本字符的匹配 当我们想查找某列中的字符中是否有

[ 学习路线 ] 2015 前端(JS)工程师必知必会 (2)

http://segmentfault.com/a/1190000002678515?utm_source=Weibo&utm_medium=shareLink&utm_campaign=socialShare 上次我写<前端工程师必知必会>已经是三年前了,那是我写过最火的文章了.三年了,我仍然会在Twitter上收到关于这篇文章的消息. 从2012年到现在,一篇文章都没发过让我觉得有点羞羞哒.三年是一段很长的时间,很多东西都发生了改变.2012年,我鼓励同学们去学习浏览器开发

.NET零基础入门09:SQL必知必会

一:前言 仿佛到了更进一步的时候了,每一个程序员迟早都会遇到数据存储的问题.我们拿什么来存储程序产生的数据?举例来说,用什么来存储我们的打老鼠游戏每次的成绩呢?选择如下: 1:内存中.缺点,退出游戏,数据就没了: 2:文件中.好办法!缺点,自己解析文本,把文本变成我们程序中的数据,这个解析的过程叫做协议.协议这个词听上去够恐怖吧,实际上说白了无非就是数据格式怎么样,API接口怎么样之类的东东. 3:数据库.好办法!好吧,数据库文件其实也就是硬盘上的文件,只不过数据库本身就已经为我们定义好了数据格