第六章
构造器初始化
初始化的顺序
在类中变量定义的顺序决定了它们初始化的顺序。即使变量定义散布在方法定义之间,它们仍会在任何方法(包括构造器)被调用之前得到初始化
// housekeeping/OrderOfInitialization.java// Demonstrates initialization order// When the constructor is called to create a// Window object, you'll see a message:class Window {Window(int marker) {System.out.println("Window(" + marker + ")");}}class House {Window w1 = new Window(1); // Before constructorHouse() {// Show that we're in the constructor:System.out.println("House()");w3 = new Window(33); // Reinitialize w3}Window w2 = new Window(2); // After constructorvoid f() {System.out.println("f()");}Window w3 = new Window(3); // At end}public class OrderOfInitialization {public static void main(String[] args) {House h = new House();h.f(); // Shows that construction is done}}
引用 w3 被初始化了两次:一次在调用构造器前,一次在构造器调用期间(第一次引用的对象将被丢弃,并作为垃圾回收)。这乍一看可能觉得效率不高,但保证了正确的初始化。
静态数据的初始化
无论创建多少个对象,静态数据都只占用一份存储区域。static关键字不能应用于局部变量,所以只能修饰属性(字段 域)。
class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
void f1(int marker) {
System.out.println("f1(" + marker + ")");
}
}
class Table {
static Bowl bowl1 = new Bowl(1);
Table() {
System.out.println("Table()");
bowl2.f1(1);
}
void f2(int marker) {
System.out.println("f2(" + marker + ")");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard {
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
bowl4.f1(2);
}
void f3(int marker) {
System.out.println("f3(" + marker + ")");
}
static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization {
public static void main(String[] args) {
System.out.println("main creating new Cupboard()");
new Cupboard();
System.out.println("main creating new Cupboard()");
new Cupboard();
table.f2(1);
cupboard.f3(1);
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
}
初始化的顺序先是静态对象(如果他们没有被初始化),然后是非静态对象。
第十一章节 内部类
当生成一个内部类的对象时,此对象与制造它的外部对象之间就有了一种联系,所以它能访问其外部对象的所有成员,而不需要任何特殊条件。此外,内部类还拥有其外部类的所有元素的访问权。
内部类自动拥有其外部类所有成员的访问权
当某个外部类的对象创建一个内部类对象时,此内部类对象必定会秘密地捕获一个指向那个外部类对象的成员。
使用 .this 和 .new
如果需要生成对外部类对象的引用,可以使用外部类的名字紧跟圆点和this。这样产生的引用自动地具有正确的类型。
public class DotThis {
void f() {
System.out.println("DotThis.f()");
}
public class Inner {
public DotThis outer() {
return DotThis.this;
// A plain "this" would be Inner's "this"
}
}
public Inner inner() {
return new Inner();
}
public static void main(String[] args) {
DotThis dt = new DotThis();
DotThis.Inner dti = dt.inner();
dti.outer().f();
}
}
有时可能想告知某些对象,去创建其某个内部类的对象。要实现此目的,必须在new表达式中提供其对外部类对象的引用。这是需要.new 语法,如下:
public class DotNew {
public class Inner {}
public static void main(String[] args) {
DotNew dn = new DotNew();
DotNew.Inner dni = dn.new Inner();
}
}
