java学习笔记—初始化与清理

  java初始化有两种,一种是在定义的时候就初始化,另外一种是在构造函数内初始化,这两种有什么区别呢?

public class Initial{
String s1="Initial at definition"
String s2;
public Initial(String s2)
{
this.s2=s2;
}
}

  s1初始化是在进入到构造函数之前,所以当Initial对象创建的时候,s2是NUll。然而调用构造函数初始化s2,可以自由的让你选择初始化的值,而s1初始化的值是写死的!

  在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,他们仍旧会在任何方法(包括构造器)被调用之前得到初始化。

  静态对象的初始化顺序先于“非静态对象”。

  

class Cup{
	public Cup(int maker) {
		// TODO Auto-generated constructor stub
	System.out.println("Cup("+maker+")");
	}
	void f(int maker){
	System.out.println("f("+maker+")");
	}
}
class Cups
{
	static Cup cup1;
	static Cup cup2;
	static{
		cup1 = new Cup(1);
		cup2 = new Cup(2);
	}
	public Cups() {
		// TODO Auto-generated constructor stub
		System.out.println("Cups()");
	}
	}
public class ExplicitStatic {
	public static void main(String[] args) {
		System.out.println("Inside main()");
		Cups.cup1.f(99);//(1)
	}
	static Cups cups1 = new Cups();//(2)
//	static Cups cups2 = new Cups();//(2)

}

  无论通过标为(1)的那行代码访问静态的cup1对象,还是把标为(1)的行注释掉,让它去运行标为(2)的那行代码,Cups的静态初始化动作都会得到执行。如果把标为(1)和(2)的行同时注释掉,Cups的静态初始化动作就不会得到执行。此外激活一行还是两行(2)的代码都无关紧要,静态初始化动作只进行一次。

  无论创建多少个对象,静态数据都只占用一份存储区域。static关键字不能应用于局部变量,因此它只能作用于域。如果一个域是静态的基本类型域,且没有对它进行初始化,那么它就会获得基本类型的标准初值;如果他是一个对象引用,那么它的默认初始化值就是null。

  静态数据都只占用一份存储区域的意思是,只要在类中定义了静态变量。则该类创建的所有对象都共享该静态数据,改变该静态变量值,同时改变所有对象的该变量!如下代码所示,输出为

initClass2.snum=88
initClass1.snum=88
initClass2.inum=200
initClass1.inum=99

 1 public class InitClass {
 2     static int snum;
 3     int inum=99;
 4     public static void main(String[] args) {
 5         InitClass initClass1 = new InitClass();
 6         InitClass initClass2 = new InitClass();
 7          snum = 88;
 8         System.out.println("initClass2.snum="+initClass2.snum);
 9         System.out.println("initClass1.snum="+initClass2.snum);
10         initClass1.inum = 200;
11         System.out.println("initClass2.inum="+initClass1.inum);
12         System.out.println("initClass1.inum="+initClass2.inum);
13     }
14 
15 }

类中变量的初始化顺序如下图所示: 

 

  为了防止程序出现不可预料的错误,JAVA编程思想这本书建议在编写构造器时:用尽可能的简单的方法使对象进入到正常状态;如果可以的话,避免调用其他方法。在构造器内唯一能够安全调用的那些方法是基类中的final方法(也适用于private方法,private方法默认是funal方法),这些方法不能被覆盖。

posted @ 2016-09-22 21:09  万物共鸣  阅读(329)  评论(0编辑  收藏  举报