初始化与清理
5.1 用构造器确保初始化
假定每个类中都有一个initizlize()方法,该方法提醒你在使用对象之前,应先调用initizlize()方法,然而用户必须记得自己去调用这个方法。Java中,通过提供构造器,类的设计者可以确保每个对象都得到初始化。
为了让编译器知道该调用哪个方法,构造器与类同名。
不接受任何参数的构造器叫做默认构造器。
构造器是一种特殊类型的方法,因为它没有返回值。
5.2 方法重载
构造器的名字是由类名决定,就只能有一个构造器名。那么想用多种方式创建一个对象怎么办?
为了让方法名相同而形参不同的构造器同时存在,必须用到方法重载。
区分重载方法:每个重载方法都必须有独一无二的参数类型列表。
5.3 默构造器
默认构造器是没有形式参数的——它的作用是创建一个默认对象。
如果你写的类中没有构造器,则编译器会自动帮你创建一个默认构造器。
如果你定义了构造器,编译器不会自动创建默认构造器。
5.4 this关键字
this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。
/**
* this返回当前对象
* @author Administrator
*
*/
public class Leaf {
int i = 0;
Leaf increment(){
i++;
return this;
}
void print(){
System.out.println("i= "+i);
}
public static void main(String[] args) {
Leaf leaf = new Leaf();
leaf.increment().increment().print();
}
}
1)在构造器里调用构造器:
public class Flower {
int petalCount = 0;
String s = "initial value";
public Flower(int petals) {
petalCount = petals;
System.out.println("Constructor w/ int arg only,"
+ "petalCount = "+ petalCount);
}
public Flower(String ss) {
System.out.println("Constructor w/ int arg only,"
+ "s = "+ ss);
s = ss;
}
public Flower(String s,int petals) {
this(petals);
//this(s) 不能调用两次
this.s = s;
System.out.println("String & int args");
}
public Flower() {
this("hi",47);
System.out.println("default constructor ,no args");
}
void printPetalCount(){
System.out.println("PetalCount = "+petalCount +" s" +s);
}
public static void main(String[] args) {
Flower flower = new Flower();
flower.printPetalCount();
}
}
输出结果为:
Constructor w/ int arg only,petalCount = 47
String & int args
default constructor ,no args
PetalCount = 47 shi
尽管可以使用this调用一个构造器,但却不能调用两个,此外,构造器必须置于最起始处,否则编译器报错。
由于参数s和数据成员s名字相同,容易产生歧义,可以用this.s = s;
解决。
2)static的含义
static方法就是没有this的方法。
static方法内部不能调用非静态方法。(可以传递一个对象引用,然后通过引用,可以调用非静态方法和非静态数据成员)
5.5 终极处理和垃圾回收
- 对象可能不被垃圾回收。
- 垃圾回收并不等于“析构”
- 垃圾回收只与对象有关。
垃圾回收器技术:
引用计数技术。自适应技术。
5.6 成员初始化
数据默认值:
对象引用如果不初始化,此引用就会获得一个特殊引用null;
在定义成员变量时可以为其指定初始值。
5.7 构造器初始化
在类的内部,变量的定义的先后顺序决定了初始化的顺序。变量初始化会在调用其他方法之前(包括构造器)。
public class OrderOfInitialValue {
public static void main(String[] args) {
House house = new House();
// house.f();
}
}
class Window{
Window(int maker) {
System.out.println("window("+maker+")");
}
}
class House {
Window w1 = new Window(1);
House() {
System.out.println("House()");
w3 = new Window(33);
}
Window w2 = new Window(2);
void f(){
System.out.println("f()");
}
Window w3 = new Window(3);
}
输出结果为:
window(1)
window(2)
window(3)
House()
window(33)
无论创建多少对象,静态数据都只占用一份存储区域。
静态对象首先回被初始化,然后再初始化“非静态”对象。
静态代码块:与其他静态初始化一样,代码块只执行一次。
5.8 数组初始化
数组是相同类型的、用一个标识符名称封装到一起的一个对象序列或者基本数据类型序列。
数组定义 int [ ] a 或者int a [ ]。现在拥有的只是对数组的引用,并没有给数组本身分配存储空间。
数组初始化方法:
int [] a = {1,2,3,4,5,6};
Integer[] a = new Integer[10];
Integer[] a = new Integer[]{
1,2,3,4,5
};
可变参数:Object… args
5.9 枚举类型
声明一个枚举类:
public enum Spiciness {
NOT,MILD,MEDIUM,HOT,FLAMING
}
枚举类与switch结合,作为switch的条件。