1.用构造器确保初始化
可以假想为编写的每个类都定义一个initialize()方法。该方法的名称提醒你在使用其对象之前,应首先调用initialize()。然而,这同时意味着用户必须记得自己去调用此方法。
从概念上讲,“初始化”与“创建”是彼此独立的,然而在上面的代码中,你却找不到对initialize()方法的明确调用。在Java中,“初始化”和“创建”捆绑在一起,两者不能分离。
2.方法重载
当创建一个对象时,也就给此对象分配到存储空间取了一个名字。
涉及基本类型的重载:
基本类型能从一个“较小”的类型自动提升至一个“较大”的类型,此过程一旦牵涉到重载,可能会造成一些混淆。
如果有某个重载方法接受int型参数,它就会被调用。至于其他情况,如果传入的数据类型(实际参数类型)小于方法中声明的形式参数类型,实际数据类型就会被提升。char型略有不同,如果无法找到恰好接受char参数的方法,就会把char直接提升至int型。
如果传入的实际参数大于重载方法声明的形式参数,会出现什么情况呢?
在这里,方法接受较小的基本类型作为参数。如果传入的实际参数较大,就得通过类型转换来执行窄化转换。如果不这样做,编译器就会报错。
以返回值区分重载方法
以下有两个方法
void f() { } int f() { return 1; }
有时你并不关心方法的返回值,则可以如此调用f()方法
f();
此时Java如何才能判断该调用哪一个f()呢?所以,根据方法的返回值来区分重载方法是行不通的。
3.this关键字
如果有两个同一类型的对象,并且此类只有一个方法,那么这个方法是被哪一个对象所调用呢?
为了能用简便,面向对象的语法来编写代码----即“发送消息给对象”,编译器做了一些幕后工作。它暗自把“所操作对象的引用”作为第二个参数传递给方法。
假设你希望在方法内部获得对当前对象的引用。有一个专门的关键字:this。
this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。
要注意的是,如果在方法内部调用同一个类的另一个方法,就不必使用this,直接调用即可。
只有需要明确指出对当前对象的引用时,才需要this关键字。例如,当需要返回对当前对象的引用时,就常常在return语句里这样写:
return this;
this关键字对于将当前对象传递给其他方法也很有用。
4.清理:终结处理和垃圾回收(跳过,有关垃圾回收器与JVM)
5.初始化
Java尽力保证:所有变量在使用前都能得到恰当的初始化。对于方法的局部变量,Java以编译时错误的形式来贯彻这种保证。
要是类的数据成员(即字段)是基本类型,情况就会变得有些不同。类的每个基本类型数据保证都会有一个初始值。
在类里定义一个对象引用时,如果不将其初始化,此引用就会获得一个特殊值null。
可以用构造器来进行初始化。但要牢记:无法阻止自动初始化的进行,它将在构造器被调用之前发生。
即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。
静态初始化只有在必要时刻才会进行。只有在第一次访问静态数据的时候,它们才会被初始化。此后,静态对象不会再次被初始化。
初始化的顺序是先静态对象(如果它们尚未因前面的对象创建过程而被初始化),而后是“非静态”对象。
总结以下对象的创建过程,假设有个名为Dog的类:
1)即使没有显式地使用static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。
2)然后载入Dog.class(后面会学到,这将创建一个Class对象),有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。
3)当new Dog()创建对象的时候,首先将堆上为Dog的对象分配足够的空间。
4)这块存储空间会被清零,这就自动地将Dog对象中的所有基本类型数据都设置成了默认值(对数字来说就是0,对布尔型和字符型也相同),而引用则被设置成了null。
5)执行所有出现于字段定义处的初始化动作。
6)执行构造器。