07. this 关键字 的用法

Author Avatar
FengXueke 10月 18, 2022
post07

this 关键字 的用法

  • 假若您希望将句柄返回给当前对象,那么它(this)经常在 return 语句中使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.isflee.c04_1_1_leaf;

//: Leaf.java
// Simple use of the "this" keyword
public class Leaf {
private int i = 0;

//将句柄返回给当前对象
Leaf increment() {
i++;
return this;
}
void print() {
System.out.println("i = " + i);
}
public static void main(String[] args) {
Leaf x = new Leaf();
x.increment().increment().increment().print();
}
} ///:~
1
2
运行结果:
i = 3
  • 在构建器里调用构建器

还有其他用法和注意点, 请看注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.isflee.c04_flower;

//: Flower.java
// Calling constructors with "this"
//在构建器里调用构建器
public class Flower {
private int petalCount = 0;
private String s = new String("null");

Flower(int petals) {
petalCount = petals;
System.out.println("Constructor w/ int arg only, petalCount= "+ petalCount);
}

Flower(String ss) {
System.out.println("Constructor w/ String arg only, s=" + ss);
s = ss;
}


Flower(String s, int petals) {
this(petals);
//! this(s); // Can't call two! 尽管可用this 调用一个构建器, 但不可调用两个。
this.s = s; // Another use of "this" 用 this.s 来引用成员数据
System.out.println("String & int args");
}

Flower() {
this("hi", 47);
System.out.println("default constructor (no args)");
}

void print() {
//! this(11); // Not inside non-constructor! 编译器不让我们从除了一个构建器之外的其他任何方法内部调用一个构建器
System.out.println("petalCount = " + petalCount + " s = " + s);
}

public static void main(String[] args) {
Flower x = new Flower();
x.print();
}
} ///:~

post07

构建器初始化

初始化顺序

在一个类里,初始化的顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间, 那些变量仍会在调用任何方法之前得到初始化——甚至在构建器调用之前。

即在同一个类中, 按照以下顺序初始化

1.static 对象

2.非static 对象

3.构造器

  • 示例1, 非static类的初始化:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.isflee.c04_1_2_garbage;

//: initialization/TerminationCondition.java
// Using finalize() to detect an object that
// hasn’t been properly cleaned up.
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");
// Normally, you’ll also do this:
// super.finalize(); // Call the base-class version
}
}
public class TerminationCondition {
public static void main(String[] args) {
Book novel = new Book(true);
// Proper cleanup:
novel.checkIn();
// Drop the reference, forget to clean up:
new Book(true);
// Force garbage collection & finalization:
System.gc();
}
} /* Output:
Error: checked out
*///:~
1
2
3
4
5
6
7
运行结果:
Tag(1)
Tag(2)
Tag(3)
Card()
Tag(33)
f()
  • 示例2, 静态数据的初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.isflee.c04_1_4_static_initialization;

//: StaticInitialization.java
// Specifying initial values in a // class definition.
class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}
class Table {
static Bowl b1 = new Bowl(1);
Table() {
System.out.println("Table()");
b2.f(1);
}
void f2(int marker) {
System.out.println("f2(" + marker + ")");
}
static Bowl b2 = new Bowl(2);
}
class Cupboard {
Bowl b3 = new Bowl(3);
static Bowl b4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
b4.f(2);
}
void f3(int marker) {
System.out.println("f3(" + marker + ")");
}
static Bowl b5 = new Bowl(5);
}

//static初始化只有在必要的时候才会进行。
//初始化的顺序是首先static(如果它们尚未由前一次对象创建过程初始化),接着是非static 对象。
//static 初始化仅发生一次 —— 在 Class 对象首次载入的时候。
public class StaticInitialization { public static void main(String[] args) {
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
new Cupboard();
t2.f2(1);
t3.f3(1);
}
static Table t2 = new Table();
static Cupboard t3 = new Cupboard();
} ///:~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
运行结果:
Bowl(1)
Bowl(2)
Table()
f(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
f2(1)
f3(1)
  • 关于static代码块(static构建从句), static{...}

与其他 static 初始化一 样,这段代码仅执行一次——首次生成那个类的一个对象时,或者首次访问属于那个类的一个 static 成员时 (即便从未生成过那个类的对象)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.isflee.c04_explicit_static;

//: ExplicitStatic.java
// Explicit static initialization // with the "static" clause.
class Cup {
Cup(int marker) {
System.out.println("Cup(" + marker + ")");
}
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}
class Cups {
static Cup c1;
static Cup c2;
static {
c1 = new Cup(1);
c2 = new Cup(2);
}
Cups() {
System.out.println("Cups()");
}
}
public class ExplicitStatic {
public static void main(String[] args) {
System.out.println("Inside main()");
//首次访问属于那个类的一个 static 成员时 (即便从未生成过那个类的对象), static{...};代码块会被才会被调用, 并且这段代码仅执行一次
Cups.c1.f(99); // (1)
}
//首次生成那个类的一个对象时,static{...};代码块会被才会被调用, 并且这段代码仅执行一次
static Cups x = new Cups(); // (2)
static Cups y = new Cups(); // (2)
} ///:~
1
2
3
4
5
6
7
运行结果:
Cup(1)
Cup(2)
Cups()
Cups()
Inside main()
f(99)

可通过注释(1)的代码 或 (2)处的代码; 或者(1)(2)都注释掉, 来观察初始化执行顺序

  • 非static构建从句

它看起来与静态初始化从句极其相似, 第七章再看吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.isflee.c04_1_5_mugs;

//: Mugs.java
// Java 1.1 "Instance Initialization"
class Mug { Mug(int marker) {
System.out.println("Mug(" + marker + ")"); }
void f(int marker) { System.out.println("f(" + marker + ")");
} }
public class Mugs { Mug c1;
Mug c2;
{
c1 = new Mug(1);
c2 = new Mug(2);
System.out.println("c1 & c2 initialized");
}
Mugs() {
System.out.println("Mugs()");
}
public static void main(String[] args) {
System.out.println("Inside main()");
Mugs x = new Mugs();
}
} ///:~
1
2
3
4
5
6
运行结果:
Inside main()
Mug(1)
Mug(2)
c1 & c2 initialized
Mugs()