java盡力保證:全部變量在使用前都能獲得恰當的初始化html
在C/C++中,變量的初始化仍是得依賴於程序員的自覺性。對於函數局部變量,編譯器不會爲基本類型賦予默認初始值,新手常常會使用未初始化的指針訪問內存,致使程序崩潰。對於類對象,編譯器將使用類的默認構造函數對對象進行初始化。而在java中,對於方法的局部變量,java以編譯時錯誤來保證變量在使用前都能獲得恰當的初始化。java
void f(){ int i ; i ++ ; //Error- - i not initialized }
儘管java編譯器也能夠爲方法的局部變量賦予一個初值,但局部變量未初始化更有多是程序員的疏忽,採用默認值反而會掩蓋這種錯誤。程序員
C++程序員剛接觸到java的類時可能會很不習慣,java類的數據成員竟然能夠在定義時就初始化:編程
public class InitialValues{ boolean bool = true; char ch = ‘x’; int i = 999; double d = 3.14; Depth d = new Depth(); }
這種方式在java中稱爲指定初始化。在指定初始化以前,編譯器還會爲這些數據成員進行默認初始化,其實是把剛分配的對象內存都置零。安全
// java數據成員的默認初始化 public class InitialValues{ boolean t; //flase char c; //[] short s; //0 byte b; //0 int i; //0 long l; //0 float f; //0.0 double d; //0.0 }
在對象裏定義一個引用,且不將其初始化時,默認初始化爲null。這種默認初始化的實現是,在建立(new)一個對象時,在堆上對對象分配足夠的空間以後,這塊存儲空間會被清零,這樣就自動把基本類型的數據成員都設置成了默認值。默認初始化動做以後,才執行指定初始化。也就是說下面的i經歷過被初始化爲0後,再賦值爲999的過程。函數
public class InitialValues{ int i = 999; }
java也可使用構造函數來進行初始化,但構造函數的初始化沒法阻止指定初始化和默認初始化的進行,並且老是在它們以後,纔會執行構造函數初始化。總結起來講,java中數據成員的初始化過程是:指針
C++禁止在定義數據成員時就進行指定初始化,並且C++也沒有默認初始化。有人會問,下面這段代碼不是默認初始化了嗎?code
class Test { public: int i; double b; char ch; }; int main() { Test *t = new Test(); cout << t->b; //輸出0 cout << t->i; //輸出0 cout << t->ch; //輸出[] return 0; }
這其實是C++的默認構造函數進行的構造函數初始化。當類沒有構造函數時,編譯器會爲類聲明並實現一個默認構造函數,默認構造函數將數據成員初始化爲默認值。因此C++數據成員的初始值,只能依賴:htm
成員初始化列表與java的指定初始化類似,也是在進入構造函數函數體以前,對數據成員進行的初始化。在數據成員的初始化順序上,java與C++卻是一致的,定義的順序決定了初始化的順序。對象
在java中不容許有static的局部變量,只可以有static的域,如static數據成員。static數據成員在對象被第一次建立時纔會被實例化,並且只實例化一次。例如:
class StaticTest{ int _a ; StaticTest (int a ){ _a = a; System.out.println("StaticTest("+a+")"); } } class Test{ static StaticTest st1= new StaticTest(1); StaticTest nonSt = new StaticTest(0); static StaticTest st2= new StaticTest(2); } public class Main { public static void main(String[] args) throws Throwable { Test t = new Test(); //直到這個時候, st1與st2纔會被實例化 } } //程序輸出 StaticTest(1) StaticTest(2) StaticTest(0)
從輸出能夠看出在java中,初始化順序是這樣的:先初始化靜態數據成員,再初始化非靜態數據成員。
在C++中,static數據成員必須在類以外初始化。關於C++的static,http://www.cnblogs.com/QG-whz/p/4473384.html 我之前的總結放在這裏挺合適的。
回到篇首的話。
java盡力保證:全部變量在使用前都能獲得恰當的初始化(《java編程思想》)
java在變量初始化上,普通變量以編譯錯誤、成員變量以默認初始化等手段,盡力使全部的變量在使用前均可獲得初始化,在安全性上大大強於C++。