每天学一点Thinking in java: 15 构造器和初始化顺序

用构造方法保证初始化

创建对象时,Java自动调用构造方法进行初始化,从而保证初始化

构造方法的特点

  1. 构造方法没有返回值;
  2. 构造方法的名称要与本类的名称相同。
    普通没有返回值的方法使用 public void methodEx()这种形式,构造方法不需要使用void关键字

定义语法

public bood{
	//…构造方法体
}

在构造方法中可以为成员变量赋值,这样当实例化一个本类的对象时,相应的成员变量也被初始化

如果类中没有明确定义构造方法,编译器会自动创建一个无参默认构造方法(no-arg default constructor)
注意:只有在类中没有定义任何构造方法时,编译器才会自动创建一个不带参数的默认构造方法,即便在类中定义的构造方法都不是无参的构造方法,编译器也不会为类设置一个默认的无参构造方法。

使用this调用构造方法:

public class AnyThing {
	public AnyThing() {
		this("this调用有参数构造方法");
		System.out.print("无参构造方法");
	}
	public AnyThing(String name) {
		System.out.print("有参构造方法");
	}
}

在无参构造方法中可以使用this关键字调用有参的构造方法,但使用这种方式需要注意只可以在无参构造方法的第一句使用this调用有参构造方法
注意:不要滥用this,不需要的时候不要使用this。只在需要的时候使用this,使代码直观,清晰,易读

初始化顺序

在一个类里,初始化的顺序是由变量在类内部定义的顺序决定。即使定义的变量散布在定义的方法之间,那些变量仍会在调用方法之前初始化——甚至在调用构建器之前。见下例:

//: OrderOfInitialization.java
// Demonstrates initialization order.
// When the constructor is called, to create a
// Tag object, you'll see a message:
class Tag {
	Tag(int marker) {
		System.out.println("Tag(" + marker + ")");
	}
}
class Card {
	Tag t1 = new Tag(1); // 在构造器之前
	Card() {
		// 表示在构造器内
		System.out.println("Card()");
		t3 = new Tag(33); // 重新初始化t3
	}
	Tag t2 = new Tag(2); // 在构造器之后
	void f() {
		System.out.println("f()");
	}
	Tag t3 = new Tag(3); // 结束
}
public class OrderOfInitialization {
	public static void main(String[] args) {
		Card t = new Card();
		t.f(); // 表示构造器结束
}
} ///:~

结果是:
Tag(1)
Tag(2)
Tag(3)
Card()
Tag(33)
f()

(Tag类在Card类之前定义,所有首先调用Tag的构造器,即便初始化Tag类的语句在Card构造器的前或后,都是优先初始化Tag,当然在Card构造器内部的初始化Tag的语句是按照Card构早起内部的顺序,建t3)
其中,t3句柄会被初始化两次,一次在构建器调用前,一次在调用期间(第一个对象会被丢弃,所以它后来会被当作垃圾收掉)

展开阅读全文