最近的工作是把幾份C++代碼翻譯成java,不搞不知道,一搞嚇一跳,真的很麻煩,C++和java的語法和其他細節差異太大了。下面就把遇到的一些差異整理總結一下:
1. 一維數組的定義:
C++:分爲靜態數組和動態數組,其中靜態數組 int a[5],或int a[2]={1,2}
動態數組 int * a= new int[5],或 int * a = new int[2](1,2)
Java: 只有動態數組,所以其語法更類似C++的動態數組 int[] a = new int[5],[]代替*
如果要初始化值 int[]a={1,2}或者int[] a=new int[]{1,2}
總結:java定義數組的特點,=左項是類型+[]+變量名,而且注意[]中不能像C++那樣帶有數組大小,而且=右項的數組和指定初始值只能出現一個,爲了方便好記,還是以int[] a = new int[5]和int[] a=new int[]{1,2}兩種寫法爲主
2. 二維數組的定義:
C++:也是分成靜態數組和動態數組,其中靜態數組 int a[2][2]或int a[2][2]={{1,2},{3,4}},動態數組int (*a) [2]=new int[2][2]或int ** a=new int*[2]
Java:只有動態數組,語法跟一維數組一樣,int[][] a=new int[2][2],或者int[][] a={{1,2},{3,4}}或者int[][] a =new int[][]{{1,2},{3,4}}
總結:java的二維數組定義注意點跟一維數組一模一樣
3. 訪問權限控制:
C++:存在權限訪問控制塊的概念,public:後續直到新權限訪問控制塊聲明前定義的成員都是public訪問控制權限
Java:不存在這種語法,每個成員都是單獨聲明訪問控制權限的,跟上下文無關
4. Class的訪問控制權限:
C++:Class關鍵字前面根本沒有訪問控制權限的概念,應該是任何其他文件都能訪問的,跟java中的public Class應該是同樣的效果
Java: Class關鍵字前面有訪問控制權限的概念,聲明爲public Class的類才能被其他所有類訪問並且必須和所在文件名同名,否則默認是包訪問控制權限,只有包內的類能訪問。
5. 構造函數(方法):
C++: 構造函數有初始化列表的概念,比如BillFileFormat::BillFileFormat(int (*fields)[2]) : _fields(fields){}
Java: 無構造方法初始化列表的概念,初始化動作直接在方法體內實現
總結:對於構造函數(方法)而言,有個很大的共同點,如果一個類沒有實現構造函數(方法),則編譯器會默認爲該類生成一個無參默認構造函數(方法),如果類實現了構造函數,則編譯器不再爲其插入。另外如果父類的構造函數(方法)是帶參數的,則子類必須實現構造函數並且顯式調用父類的構造函數(方法),否則會出現編譯錯誤,如果父類有無參(默認)構造函數(方法),則子類無需顯示調用父類的構造函數(方法),編譯器會自動插入調用父類無參(默認)構造函數(方法)。總而言之,不管是顯式調用還是編譯器幫忙插入,子類是必須調用父類的構造函數(方法)的,當然如果父類有無參(默認)構造函數(方法),我們就不需要顯式編碼,一切由編譯器幫忙插入。另外java調用構造函數(方法)的語法是super(父類構造方法參數1,父類構造方法參數2,……)
6. 枚舉類型:
C++:在C++中枚舉的概念相對簡單,使用也比較簡捷,它更接近成員常量,而非類
// input is 0, output is 1, and appendis 2
enum open_modes {input, output,append};
--{}裏面的各個值默認從0開始,自增1,爲整數,某種程度而言它更像宏定義或者常量,編譯是會直接被數值替換掉,唯一比較麻煩和讓人誤解的是對C++的enum變量的賦值,不能直接用整數賦值,必須用枚舉成員或者枚舉對象才能賦值,比如:open_modes a = 1//error,
open_modesb= input//ok。雖然網上找不到C++中枚舉編譯器處理後的底層實現,但是我認爲C++的枚舉更像是依賴於編譯器處理替換成常量整數的一種語法規範,而不是真正意義上的類,跟宏定義或者常量更像,只不過外表披了一層類的外衣。
Java: 在java中枚舉本質上是個類,只不過爲了兼容C++枚舉的概念,也起了enum的名字,但是實際使用上差別非常大,在java中enum 的語法結構儘管和 class 的語法不一樣,但是經過編譯器編譯之後產生的是一個class文件,如上述C++的例子在java的實現編譯後如下
publicclass open_modes extends java.lang.Enum{
public static final open_modes input;
public static final open_modes output;
public static final open_modes append;
new Enum<EnumTest>(" input ",0);
new Enum<EnumTest>(" output",1);
new Enum<EnumTest>(" append",2);
}
--可見本質是繼承java.lang.Enum<E>的子類,枚舉裏面的成員其實是靜態子類常量對象。進去java.lang.Enum源碼裏面可以發現
privatefinal String name;
privatefinal int ordinal;
protectedEnum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
--所以java中枚舉本質是調用了Enum的構造方法把枚舉成員名字和一個從0開始自增(編譯器幫忙插入代碼)整數作爲傳入參數,創建了靜態子類常量對象。
總結:在C++中,枚舉經常當整形常量成員使用,比如int a[append];相當於int a[2],根本沒有顧及所屬的枚舉類型,而在java中,如果要實現這種用法就要int[] a =new int[open_modes.Input. ordinal()]