构造器的作用是在new一个对象时对其进行初始化操作。使用new初始化一个对象的过程如下:
(1)
首先执行静态代码块,若该类有父类则先执行父类的静态代码块。
(2)
接着执行该类的构造方法,若该类有父类,则先执行父类的构造方法。由此可以形成一条构造方法链,直到顶层父类。
执行如下代码:
public class ObjTest {
public static void main(String[] args) {
Children obj = new Children();
}
}
class Children extends Parent{
static{
System.out.println("children static block...");
}
public Children(){
System.out.println("children constructor block....");
}
public void test() {
System.out.println("instance block....");
}
}
class Parent{
static{
System.out.println("parent static block...");
}
public Parent(){
System.out.println("parent constructor block...");
}
}
结果为:
parent static block...
children static block...
parent constructor block..
children constructor block....
由此我们可以了解到对象初始化的过程,这其中最重要的就是构造方法,构造方法是对一个对象进行初始化的操作。接下来说说构造方法。当我们没有为一个类指定构造方法时,编译程序会自动生成一个空构造方法。当我们为一个类指定一个非空构造方法时,编译程序就不会自动生成一个构造方法。
比如:
class Obj{
public static void main(String[] args) {
new Obj();
}
}new Obj()的作用就是新建一个对象,并调用默认构造器,即使我们没有指定构造器。
若修改代码如下:
class Obj{
public static void main(String[] args) {
new Obj();
}
public Obj(int a){
}
}
则编译器就会报错,因为我们已经指定了一个构造方法。就好象我们没有设置任何构建器,
编译程序会说:“你看来似乎需要一个构建器,所以让我们给你制造一个吧。”但假如我们写了一个构建器,编译程序就会说:“啊,你已写了一个构建器,所以我知道你想干什么;如果你不放置一个默认的,是由于你打算省略它。”
因此当我们顶一个类时,若指定了非空的构造方法时,一般也需要手动指定一个非空的构造方法,便于类的继承。
接下来说说this关键字,this关键字代表当前对象。
首先看下面的代码:
class Obj{
void f(int i){
}
public void test() {
Obj a = new Obj(),b = new Obj();
a.f(1);
b.f(2);
}
}
这是一个普通的对象调用方法,它内部是如何实现的呢?其实如下,
Obj.f(a,1);Obj.f(b,2);就是为某个方法指定一个句柄。我们也可以使用this关键字调用,this.f(1);但是事实上没有必要的,编译器会自动帮我们完成。但是对于那些特殊的类--需要明确使用当前对象的句柄,将当前对象的句柄返回时,需要使用this。
class Obj{
int a = 0;
void g(){
test().test().test();
}
Obj test(){
a++;
return this;
}
}
我们可以这样构造一个方法链。
若为一个类写了多个构建器,那么经常都需要在一个构建器里调用另一个构建器,以避免写重复的代码。可用this关键字做到这一点
class Obj{
int a = 0;
public Obj(int a){
this.a = a;
}
public Obj(String s){
}
public Obj(){
this(4);
//this("aa");
System.out.println("....");
}
} 使用this可以在构造器里调用另一个构造器,而且this语句必须是第一条语句,并且不能使用两个this语句。在第一个构造器里,成员变量和局部变量重名了,还可以使用this关键字调用成员变量。 在对象的初始化过程中我们也说到了static关键字,static关键字修饰的成员变量,方法都属于类方法,是全局的,该类的所有实例都共享这些数据,不需要创建对象就可以使用这些数据。实例变量,实例方法(没有static修饰的)是属于某个实例的,必须先创建一个实例才可以使用这些数据.因此在静态方法中不可以调用实例方法,因为实例方法需要确定对象。需要说明一点,静态代码块。静态代码块在类的字节码加载时执行,可以做些全局的初始化操作。而构造方法,做某个具体实例的初始化操作。