Java與C++變數初始化的對比

來源:互聯網
上載者:User

Java與C++變數初始化的對比

Java儘力保證:所有變數在使用前都能得到恰當的初始化

①函數/方法局部變數的初始化

在C/C++中,變數的初始化還是得依賴於程式員的自覺性。對於函數局部變數,編譯器不會為基本類型賦予預設初始值,新手經常會使用未初始化的指標訪問記憶體,導致程式崩潰。對於類對象,編譯器將使用類的預設建構函式對對象進行初始化。而在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)一個對象時,在堆上對對象分配足夠的空間之後,這Block Storage空間會被清零,這樣就自動把基本類型的資料成員都設定成了預設值。預設初始化動作之後,才執行指定初始化。也就是說下面的i經曆過被初始化為0後,再賦值為999的過程。

public class InitialValues{int i = 999;}

java也可以使用建構函式來進行初始化,但建構函式的初始化無法阻止指定初始化和預設初始化的進行,而且總是在它們之後,才會執行建構函式初始化。總結起來說,java中資料成員的初始化過程是:

  • ① 先預設初始化
  • ② 進行定義處的初始化(指定初始化)
  • ③ 建構函式初始化

C++禁止在定義資料成員時就進行指定初始化,而且C++也沒有預設初始化。有人會問,下面這段代碼不是預設初始化了嗎?

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++資料成員的初始值,只能依賴:

  • 成員初始化列表
  • 建構函式

成員初始化列表與java的指定初始化相似,也是在進入建構函式函數體之前,對資料成員進行的初始化。在資料成員的初始化順序上,java與C++倒是一致的,定義的順序決定了初始化的順序。

關於static成員的初始化

在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, 見 。

回到篇首的話。

Java儘力保證:所有變數在使用前都能得到恰當的初始化(《Java編程思想》) pdf下載見

Java在變數初始化上,普通變數以編譯錯誤、成員變數以預設初始化等手段,儘力使所有的變數在使用前都可得到初始化,在安全性上大大強於C++。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.