Java尽力保证:所有变量在使用前都能够恰当的初始化。
1)方法的局部变量。Java以编译时错误来贯彻这种保证。eg:
void f(){ int i; i++; //Error , i not initialized }2)类的数据成员。如果是基本类型,他们都会有一个初始值;如果是对象引用,那么这个引用将会被初始化为null。
如果想为某个变量赋值,该怎么做?
1)直接在定义类成员变量的地方为其赋值(注意,C++里面是不可以的,尽管C++新手们总想这么做)
class Depth{} public class InitialValues{ boolean bool = true; char ch = 'x'; int i = 999; Depth d = new Depth(); }2)调用某个方法来提供初始值。
public class MethodInit{ int i = f(); int f(){return 11;} }这个函数还可以带参数,但必须是初始化过的参数。
public class MethodInit2{ int i = f(); int j = g(i); int f(){ return 11; } int g(int n){ return n*10; } }但下面的写法确实错误的
public class MethodInit3{ // int j = g(i) ; //Illegal forward reference int i = f(); int f(){return 11;} int g(int n){return n*10;} }显然,上述程序的正确性取决于 初始化的顺序。编译器会发出“向前引用”的警告。
上述这种在定义的地方就初始化,简单快捷,这样创造出来的每个对象都会具有相同的值。
在C++里面叫做构造函数,这里我们叫做构造器,都一个东西。上一节讲到的自动初始化是一定会被执行的,而且会在构造器之前执行。
public class Counter{ int i; Counter(){i = 8;} }上述代码,i首先会被置为0,然后变为7.
class Window{ Window(int marker){print("window("+marker+")");} } class House{ window w1 = new Window(1); House(){ print("house()"); w3 = new Window(33); } Window w2 = new Window(2); void f(){print("f()");} Window w3 = new Window(3); } public class OrderOfInitialization{ public static void main(String[] args){ House h = new House(); h.f(); } } /**Output**/ /* Window(1) Window(2) Window(3) House() Window(33) f()*/
class Bowl{ Bowl(int marker){print("Bowl("+marker+")");} void f1(int marker){print("f1("+marker+")");} } class Table{ static Bowl bowl1 = new Bowl(1); Table(){ print("Table()"); bowl2.f1(1); } void f2(int marker){ print("f2("+marker+")"); } static Bowl bowl2 = new Bowl(2); } class Cupboard{ Bowl bowl3 = new Bowl(3); static Bowl bowl4 = new Bowl(4); Cupboard(){ print("Cupboard()"); bowl4.f1(2); } void f3(int marker){ print("f3("+marker+")"); } static Bowl bowl5 = new Bowl(5); } public class StaticInitialization{ public static void main(String[] args){ print("Creating new Cupboard() in main"); new Cupboard(); print("Creating new Cupboard() in main"); new Cupboard(); table.f2(1); cupboard.f3(1); } static Table table = new Table(); static Cupboard cupboard = new Cupboard(); } /**output*/ /* Bowl(1) Bowl(2) Table() f1(1) Bowl(4) Bowl(5) Bowl(3) Cupboard() f1(2) Creating new Cupboard in main Bowl(3) Cupboard() f1(2) Creating new Cupboard in main Bowl(3) Cupboard() f1(2) f2(1) f3(1) */请务必细心的看上述代码和结果。最好自己能够运行一遍。
public class Spoon{ static int i; static { i = 47; } }上述代码和静态初始化动作是一样的,代码仅在必要的时刻仅执行一次。
class Cup{ Cup(int marker){ print("Cup("+marker+")"); } void f(int marker){ print("f("+marker+")"); } } class Cups{ static Cup cup1; static Cup cup2; static { cup1 = new Cup(1); cup2 = new Cup(2); } Cups(){ print("Cups()"); } } public class ExplicitStatic{ public static void main(String[] args){ print("Inside main()"); Cups.cup1.f(99);//(1) } //static Cups cups1 = new Cups();//(2) //static Cups cups2 = new Cups();//(3) } /**output*/ /* Inside main() Cup(1) Cup(2) f(99) */上述代码无论是运行(1)还是把(1)注释了运行(2),Cups的静态初始化都会得到执行。(3)也可以打开看看,无关紧要,因为静态初始化动作只进行一次。
class Mug{ Mug(int marker){ print("Mug("+marker+")"); } void f(int marker){ print("f("+marker+")"); } } public class Mugs{ Mug mug1; Mug mug2; { mug1 = new Mug(1); mug2 = new Mug(2); printf("mug1 & mug2 initialized"); } Mugs(){ print("Mugs()"); } Mugs(int i){ print("Mugs(int)"); } public static void main(String[],args){ print("Inside main()"); new Mugs(); print("new Mugs() completed"); new Mugs(1); print("new Mugs(1) completed"); } } /** output*/ /* Inside main() Mug(1) Mug(2) mug1 & mug2 initialized Mugs() new Mugs() completed Mug(1) Mug(2) mug1 & mug2 initialized Mugs(int) new Mugs(1) completed */