第4章 初始化和清理
1.构造函数
是与类名字相同的一种特殊函数
提供构造函数,可以确保对象的初始化动作一定会被执行
<构造函数是不会返回任何东西的>
没有自定义任何构造函数 编译器会调用默认的构造器
如果定义了构造器(有或者无参数) 编译器就不会为你分配构造器
2.关键字this
仅用于函数之内 能够唤起此函数所在的那个类的引用
以下引用Sun的JLS关于this关键字的说明:
The keyword this may be used only in the body of an instance method,
instance initializer or constructor, or in the initializer of an instance variable of a class.
If it appears anywhere else, a compile-time error occurs.
When used as a primary expression, the keyword this denotes a value that is a reference
to the object for which the instance method was invoked ,
or to the object being constructed. The type of this is the class C within which the keyword this occurs.
At run time, the class of the actual object referred to may be the class C or any subclass of C.
翻译一下就是:
<E文太烂>
关键字this应该仅仅被用在实例化方法,实例初始化(??)或者构造器,又或者在类的实例化变量的初始化时(??)<像是下面Flower(String s, int petals)构造器中s的赋值??>
如果它出现在其他地方,将会在编译时发生错误.
当被使用在主表达式时,关键字this表示的是一个指向在实例化方法中调用的类或者是正在被构造的类的引用.
This在关键字发生类C的内部.在运行的时候,事实上指向的是类C或者类C的子类 .
一段来自Think in java 2中有关构造函数以及this的代码:
2
3 int petalCount = 0 ;
4 String s = new String( " null " );
5
6 Flower( int petals)
7 {
8 petalCount = petals;
9 System.out.println( " Constructor w/ int arg only, petalCount= " + petalCount);
10 }
11
12 Flower(String ss)
13 {
14 System.out.println( " Constructor w/ String arg only, s= " + ss);
15 s = ss;
16 }
17
18 Flower(String s, int petals)
19 {
20 this (petals);
21 // this(s); // Can't call two!
22 this .s = s; // Another use of "this"
23 System.out.println( " String & int args " );
24 }
25
26 Flower()
27 {
28 this ( " hi " , 47 );
29 System.out.println( " default constructor (no args) " );
30 }
31
32 void print()
33 {
34 // ! this(11); // Not inside non-constructor!
35 System.out.println( " petalCount = " + petalCount + " s = " + s);
36 }
37
38 public static void main(String[] args)
39 {
40 Flower x = new Flower();
41 x.print();
42 }
43
44
45 }
运行结果是:
String & int args
default constructor (no args)
petalCount = 47 s = hi
代码28行this("hi",47)调用构造器Flower(String s, int petals)
在构造器Flower(String s, int petals)里的 this.s=s 是将参数s值赋给类变量s
因而才会在最后打印出 s=hi
要是注释掉此行 结果是 s=null
编译器不允许你构造在函数之外的任何函数内调用构造函数
3.成员初始化
class的数据成员属于基本数据类型时,可以不用给予初始化
编译器会默认给予初始值
不论变量的位置如何 变量一定会在任何一个函数(甚至构造函数)被调用之前完成初始化
一段书上的代码:
Tag( int marker) {
System.out.println( " Tag( " + marker + " ) " );
}
}
class Card {
Tag t1 = new Tag( 1 ); // Before constructor
Card() {
// Indicate we're in the constructor:
System.out.println( " Card() " );
t3 = new Tag( 33 ); // Reinitialize t3
}
Tag t2 = new Tag( 2 ); // After constructor
void f() {
System.out.println( " f() " );
}
Tag t3 = new Tag( 3 ); // At end
}
public class OrderOfInitialization {
public static void main(String[] args) {
Card t = new Card(); // 程序入手点
t.f(); // Shows that construction is done
}
}
Tag( 2 )
Tag( 3 )
Card()
Tag( 33 )
f()
在调用Card()构造器之前 先要对类Card里的成员变量初始化
Tag t1 = new Tag(1);
Tag t2 = new Tag(2);
Tag t3 = new Tag(3);
初始化一个就调用Tag(int maker)构造器一次
所以才会打印出 Tag(1) Tag(2) Tag(3)
初始化完成以后 才调用Card()构造器
static变量的初始化都只占用一份空间 因而也就是说static一经初始化以后
static变量将不再被初始化
初始化时 static变量初始化顺序先于non-static
4.对象生成过程:摘自原书
<务必清楚这个过程>
以一个名为Dog的class为例:
1.当Dog对象首次被产生出来,Java直译器必须查找环境变量所在的位置,找出Dog.class
2.Dog.class被装载,它所有的static初始化动作将执行,而且仅会执行1次,就在class首次被装载的时候
3.当new Dog()时,构建过程会为Dog对象在heap上分配足够的空间
4.存储空间会先被清为零,并自动将Dog对象所有基本数据类型的数据设置为初始值,将引用设为null
5.执行所有出现于数据定义处的初始化动作
6.执行构造函数
5.数组初始化
数组是一连串对象或者一连串基本数据 它们都必须是同型的
将某个数组指派给另外个数组 所操作的仅仅是数组的引用而已
换句话说就是说被赋值的一方改变数组值的同时 赋值一方也会随着改变
TO BE CONTINUED ......
MACINTER.