初始化与清理
随着计算机革命的发展,“不安全”的编程方式已逐渐成为编程代价高昂的主因之一。
5.1用构造器确保初始化
构造器是一种特殊类型的方法,因为它没有返回值。构造器采用与类相同的名称,通过提供构造器,类的设计者可确保每个对象都会得到初始化。其中,不接受任何参数的构造器叫做默认构造器,也叫无参构造器。
5.2方法重载
方法名相同而形参不同的方法同时存在成为方法重载。
每个重载方法都必须有一个独一无二的参数列表,甚至参数顺序的不同也足以区分两个方法。
5.3默认构造器
作用:创建一个默认对象,如果你写的类中没有构造器,则编译器会自动帮你创建一个默认构造器。如果已经定义了一个构造器(无论是否有参数),编译器就不会帮你自动创建默认构造器。
5.4this关键字
只能在方法内部使用,表示对“调用方法的那个对象”的引用。
this的用法和其他对象引用并无不同。
注意,在方法内部调用另一个方法,就不必使用this,直接调用即可。
this关键字可用于返回当前对象的引用,将当前对象传递给其他方法,以及在构造器中调用构造器。
注意,只能用this调用一个构造器,并且必须置于最起始处。
另,static方法就是没有this的方法。
5.5清理:终结处理和垃圾回收
finalize():一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。
1、对象可能不被垃圾回收
2、垃圾回收并不等于“析构”
3、垃圾回收只与内存有关
finalize()的使用需求:通过某种创建对象以外的方式为对象分配了存储空间。比如调用了C语言的malloc()方法,需要在finalize()中用本地方法调用free()。
finalize()另一个用法:验证对象终结条件。
实例:
class Book{
boolean checkedOut = false;
Book(boolean checkOut){checkedOut = checkOut;}
void checkIn(){checkedOut=false;}
protected void finalize(){
if(checkedOut){System.out.println("Error:checked out");
}
}
public class TerminationCondition{
public class void main(String[] args){
new Book(true);
System.gc();
}
本例的终结条件是:所有的Book对象在被当作垃圾回收之前都应该被签入(check in)。但是在main函数中,由于程序员的错误,有一本书未被签入,要是没有finalize方法来验证终结条件,将很难发现这种缺陷。
5.6成员初始化
Java尽力保证:所有变量在使用前都能得到恰当的初始化。对于方法的局部变量,Java以编译时错误的形式来贯彻这种保证。
指定初始化示例:
public class Demo{
boolean bool = true;
int n = 6;
}
5.7构造器初始化
注:自动初始化将在构造器被调用之前发生。
public class Counter {
int i;
Counter() { i = 7;}
}
此代码,首先i会初始化为0,然后变成7。因此,编译器不会强制你一定要在构造器的某个地方或在使用它们之前对元素进行初始化——因为初始化已经得到了保证。
静态初始化:static域的初始化。(只在必要时刻才会进行)。
对象创建过程总结,假设有一个Dog类:
1、即使没有显式地使用static关键字,构造器实际上也是静态方法。当首先创建类型为Dog的对象时,或者Dog类的静态方法/域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。
2、载入Dog.class,有关静态初始化的所有动作都会执行。静态初始化只在Class对象首次加载的时候进行一次。
3、当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。
4、这块存储空间会被清零。自动将对象中所有基本类型数据设置成默认值,引用设置为null值。
5、执行所有出现于字段定义处的初始化动作。
6、执行构造器。
显示的静态初始化:
public class Spoon{
static int i;
static{ i = 47;}
}
这段static代码只执行一次:当首次生成这个类的一个对象时,或者首次访问属于那个类的静态数据成员时(即便从未生成过这个类的对象)。
非静态实例初始化:
public class Demo{
int i;
{i=5;}
}
该初始化使得你可以保证无论调用了哪个显式构造器,某些操作都会发生。
5.8数组初始化
int[] a = {1,3,5};
Integer[] a = new Integer[]{
new Integer(2);
new Integer(4);
}
可变参数列表
public class Demo{
static void printArray(Object[] args){
for(Object obj : args){
System.out.println(obj + " ");
}
}
static void printArray(Object... args){
for(Object obj : args){
System.out.println(obj + " ");
}
}
}
5.9枚举类型
enum关键字,Java SE5添加的新特性
public enum Spiciness{NOT, MILD, MEDIUM, HOT, FLAMING}
public class SimpleEnumUse{
public static void main(String[] args){
Spiciness howHot = Spiciness.HOT;
System.out.println(howHot);
for(Spiciness s : Spiciness.values()){
System.out.println(s+ ". ordinal " + s.ordinal());
}
}
}
enum特性:可用于switch语句