构建对象1

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011733020/article/details/86034580

 默认构建器


正如早先指出的那样,默认构建器是没有自变量的。它们的作用是创建一个“空对象”。若创建
一个没有构建器的类,则编译程序会帮我们自动创建一个默认构建器。例如:
//: DefaultConstructor.java
class Bird {
     int i;
}
public class DefaultConstructor {
  public static void main(String[] args) {
    Bird nc = new Bird(); // default!
 }
} ///:~
对于下面这一行:
new Bird();


方法过载

它的作用是新建一个对象,并调用默认构建器——即使尚未明确定义一个象这样的构建器。
若没有它,就没有方法可以调用,无法构建我们的对象。然而,如果已经定义了一个构建器
(无论是否有自变量),编译程序都不会帮我们自动合成一个:
class Bush {
Bush(int i) {}
Bush(double d) {}
}
现在,假若使用下述代码:
new Bush();
编译程序就会报告自己找不到一个相符的构建器。就好象我们没有设置任何构建器,编译程
序会说:“你看来似乎需要一个构建器,所以让我们给你制造一个吧。”但假如我们写了一个构
建器,编译程序就会说:“啊,你已写了一个构建器,所以我知道你想干什么;如果你不放置
一个默认的,是由于你打算省略它。”

在构建器里调用构建器

//: 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.s = s; // Another use of "this"
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();
}
} ///:~

 

 

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

 


public class Bowl {
	Bowl(int marker) {
		System.out.println("Bowl(" + marker + ")");
		}
		void f(int marker) {
		System.out.println("f(" + marker + ")");
		}
}
public 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);
}

public 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);
}
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();

}

结论是:

静态成员先初始化, 然后对象通过构造初始化初始化,会先初始化,对象中的引用的其他成员对象,最后才初始化构造方法。

在这里有必要总结一下对象的创建过程。请考虑一个名为Dog的类:


(1) 类型为Dog的一个对象首次创建时,或者Dog类的static方法/static字段首次访问时,Java解
释器必须找到Dog.class(在事先设好的类路径里搜索)。
(2) 找到Dog.class后(它会创建一个Class对象,这将在后面学到),它的所有static初始化模块
都会运行。因此,static初始化仅发生一次——在Class对象首次载入的时候。
(3) 创建一个new Dog()时,Dog对象的构建进程首先会在内存堆(Heap)里为一个Dog对象分
配足够多的存储空间。
(4) 这种存储空间会清为零,将Dog中的所有基本类型设为它们的默认值(零用于数字,以及
boolean和char的等价设定)。
(5) 进行字段定义时发生的所有初始化都会执行。
(6) 执行构建器。正如第6章将要讲到的那样,这实际可能要求进行相当多的操作,特别是在涉
及继承的时候。

猜你喜欢

转载自blog.csdn.net/u011733020/article/details/86034580