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

简介:

面向对象编程中,编程人员应该在意“资源”。比如

?
1
String hello = "hello";

在代码中,我们很在意在内存String类型hello,它是有一个生命周期的。在它生命周期中,初始化(initialization)清理(cleanup)是两个重要的环节。尤其是C程序中,很多bug会出现在对象初始化清理的环节。这样会造成一些程序安全问题。

《Think in Java》中说道:

随着计算机革命的发展,”不安全“的编程方式已逐渐成为编程代价高昂的主因之一。

一、栈与堆

在Java开发中,针对对象会在乎内存的两个区域:对象的生存空间是堆(heap) — 方法调用及局部变量(也称变量)的生存空间栈(stack)。如图:

绘图1

 

二、什么是构造器,默认(无参)构造器

为了保证对象成功初始化,Java像C++一样引入了构造器(Constructor),即在创建对象的时候被自动调用的特殊方法。自然,Java额外提供了GC(垃圾回收器),对于不再使用的资源,垃圾回收机制会自动释放资源。Java通过类构造器创建新对象的时候,在使用此对象前,会调用其构造器进行初始化。如:

?
1
2
3
4
5
6
7
8
9
10
public class VoidConstructor {
     
     VoidConstructor(){
         // 构造器
     }
     
     void VoidConstructor() {
         // void 方法,不是构造器
     }
}

1、默认构造器

这里,VoidConstructor是一个类,如果需要创建一个VoidConstructor对象只要

?
1
VoidConstructor constr = new VoidConstructor();

调用上面的代码就可以通过这个默认构造器(即无参构造器),就生成一个VoidConstuctor对象。代码图解如下

绘图2

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

image

上面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
22
/**
  * @author Jeff Lee
  * @since 2015-9-10 08:56:18
  * 继承中的构造器的案例
  */
public class ChildConstructor extends PersonConstructor{
     ChildConstructor() {
  //super();
         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函数运行结果如下:

image

 

1. 先分析下类UML,ChildConstructor 继承 PersonConstructor,PersonConstructor 继承 Object:

 

绘图3

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. 过程流程图详解(图中是各对象构造器在堆栈块中调用流程 图中引用两字有歧义):

绘图4

五、总结

 

构造器虽小,关键还是非常关键的。

本文小结:

1、默认构造器

2、有参构造器

3、继承中的构造器

还有第一点的知识基础补充

相关文章
|
3月前
|
Java 编译器
java“变量 x 可能未被初始化”解决
在Java中,如果编译器检测到变量可能在使用前未被初始化,会报“变量 x 可能未被初始化”的错误。解决方法包括:1. 在声明变量时直接初始化;2. 确保所有可能的执行路径都能对变量进行初始化。
301 2
|
2月前
|
Java
Java 静态变量的初始化顺序
【10月更文挑战第15天】了解 Java 静态变量的初始化顺序对于正确编写和维护代码至关重要。通过深入理解初始化顺序的原理和细节,我们可以更好地避免潜在的问题,并提高代码的质量和可靠性。
|
3月前
|
Java 编译器
【一步一步了解Java系列】:子类继承以及代码块的初始化
【一步一步了解Java系列】:子类继承以及代码块的初始化
146 3
|
3月前
|
Java
java构造方法时对象初始化,实例化,参数赋值
java构造方法时对象初始化,实例化,参数赋值
95 1
|
4月前
|
Oracle Java 关系型数据库
【颠覆性升级】JDK 22:超级构造器与区域锁,重塑Java编程的两大基石!
【9月更文挑战第6天】JDK 22的发布标志着Java编程语言在性能和灵活性方面迈出了重要的一步。超级构造器和区域锁这两大基石的引入,不仅简化了代码设计,提高了开发效率,还优化了垃圾收集器的性能,降低了应用延迟。这些改进不仅展示了Oracle在Java生态系统中的持续改进和创新精神,也为广大Java开发者提供了更多的可能性和便利。我们有理由相信,在未来的Java编程中,这些新特性将发挥越来越重要的作用,推动Java技术不断向前发展。
|
5月前
|
安全 Java 关系型数据库
Java连接Mysql SSL初始化失败
Java连接Mysql SSL初始化失败
|
5月前
|
存储 Java
如何在 Java 中初始化二维 ArrayList
【8月更文挑战第23天】
112 1
|
5月前
|
存储 Java 编译器
如何在 Java 中初始化对象 Arraylist?
【8月更文挑战第23天】
150 0
|
5月前
|
存储 Java 开发工具
【Azure Developer】VS Code运行Java 版Azure Storage SDK操作Blob (新建Container, 上传Blob文件,下载及清理)
【Azure Developer】VS Code运行Java 版Azure Storage SDK操作Blob (新建Container, 上传Blob文件,下载及清理)
|
5月前
|
Java Spring
Java SpringBoot Bean InitializingBean 项目初始化
Java SpringBoot Bean InitializingBean 项目初始化
73 0