Java 深入学习(17) —— 类的初始化

来源:互联网 发布:南京润和软件 编辑:程序博客网 时间:2024/06/02 04:00

1 用构造器确保初始化

在 Java 中,通过提供构造器,类的设计者可以确保每个对象都会得到初始化。

构造器的名称必须与类名完全相同。

不接受任何参数的构造器叫 默认构造器。

有了构造器形式参数,就可以在初始化对象时提供实际参数。

在 Java 中,“初始化” 和 “创建” 捆绑在一起,两者不能分离。

构造器是一种特殊类型的方法,因为它没有返回值。


2 默认构造器

默认构造器(又称“无参”构造器),如果你写的类中没有构造器,则为编译器会自动帮你创建一个默认构造器。

这里写图片描述

上图中,创建对象时,调用了 编译器自动创建的默认构造器


如果已经定义了一个构造器(无论是否含有参数),编译器就不会帮你自动创建默认构造器。

这里写图片描述


3 this 关键字

this 关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。

  • 注意:如果在方法内部调用同一个类的另一个方法,就不必写 this,直接调用即可。

这里写图片描述


  • 只有当需要明确指出对当前对象的引用时,才需要使用 this 关键字。

这里写图片描述


  • 使用 this 关键字,将当前对象传递给其他方法

这里写图片描述


  • 使用 this 关键字,在一个构造器中调用另一个构造器

这里写图片描述

注意:尽管可以用 this 调用一个构造器,但却不能调用两个。此外构造器调用必须置于最起始处,否则会报错!

这里写图片描述

这里写图片描述


4 成员初始化

在类内部,对于成员变量,如果在定义的时候没有进行显示的赋值初始化,则Java会保证类的每个成员变量都得到恰当的初始化:

  1)对于 char、short、byte、int、long、float、double等基本数据类型的变量来说会默认初始化为0(boolean变量默认会被初始化为false);

  2)对于引用类型的变量,会默认初始化为null。

这里写图片描述


5 构造器初始化


无法阻止自动初始化的进行,它将在构造器被调用之前发生。

public class Counter {  int i;  Counter() { i = 7; }  // ...} ///:~

i 首先会被置为 0, 然后变为 7


6 初始化顺序


6.1 非静态实例初始化


在创建对象的过程中,会先初始化对象的成员变量,然后再执行构造器。也就是说类中的变量会在任何方法(包括构造器)调用之前得到初始化,即使变量散布于方法定义之间。

这里写图片描述


6.2 静态实例初始化


当程序执行时,需要创建某个类的对象,JVM 会先检查是否加载了这个类,如果没有加载,则先执行类的加载再创建对象,如果已经加载,则直接生成对象。

类的加载过程中,类的static成员变量会被初始化,另外,如果类中有static语句块,则会执行static语句块。static成员变量和static语句块的执行顺序同代码中的顺序一致。记住,在Java中,类是按需加载,只有当需要用到这个类的时候,才会加载这个类,并且只会加载一次。看下面这个例子就明白了:

这里写图片描述

这里写图片描述

无论创建多少个对象,静态数据都只占用一份存储区域。只有在第一个包含静态数据的对象被创建(或者第一次访问静态数据)的时候,他们才会被初始化。此后,静态对象不会被再次初始化。

.总结一下对象创建过程,假设有个名为Dog的类:

(1)当首次创建类型为Dog的对象时(构造器可以看成是静态方法),或者Dog类的静态方法/静态字段首次被访问时,Java解释器必须查找路径,以定位Dog Class文件。(2)然后载入DogClass,有关静态初始化的所有动作都会执行,因此,静态初始化只在DogClass首次加载的时候进行一次。(3)当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。(4)这块存储空间会被清零,这就自动的将Dong对象中所有的基本类型数据都设置成了缺省值(对数字来说是0,对布尔型和字符型也相同),而引用则被设置成Null。(5)执行所有出现于字段定义处的初始化动作。(6)执行构造器

6.3 数组初始化


所有的数组都有一个length成员,用来表示该数组内包含了多少个元素,不能对其修改。

  1. 如果数组元素是基本类型:int[] a = new int[20]; 或者 int[] a = {1,2,3,4,5};

  2. 如果数组元素不是基本数据类型,那么必须使用new,创建的数组里的每个元素都是一个引用,即便使用new创建数组后,它还只是一个引用数组,并且直到通过创建新的Integer对象,并把对象赋值给引用,初始化才算结束。如下:

Integer[] a = new Integer[20];a[i] = new Integer(rand.nextInt(400));如果忘记了创建对象,并且试图使用数组中的空引用,则在运行时会产生异常。
也可以使用花括号:Integer[] a = (new Integer(1),new Integer(2),);或者:Integer[] a = new Integer[] {new Integer(1),new Integer(2),}
  1. 多维数组:一维的扩展。

7 Reference

1、《Java核心思想》第5章初始化与清理

2、Java:类与继承
http://www.cnblogs.com/dolphin0520/p/3803432.html


阅读全文
0 0
原创粉丝点击